微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

bash – 解释器是否读取了#!/ bin / sh?

在bash或sh中,我猜任何以#开头的都是评论.

但是在bash脚本中我们写道:

#!/bin/bash

在Python脚本中,有:

#!/bin/python

这是否意味着#本身就是一个评论而#!不是?

解决方法:

#!在脚本运行之前使用line,然后在脚本运行时忽略.

你问的是shebang line和普通评论之间有什么区别.

一行以#开头!与#开头的任何其他行一样多.如果是#,这是真的!是文件的第一行,或其他任何地方. #!/ bin / sh有效,但解释器本身无法读取.

#不是所有编程语言中的注释,但是,正如您所知,它是Bourne样式shell中的注释,包括sh和bash(以及大多数非Bourne样式的shell,如csh).它是also a comment in Python.它是各种配置文件中的注释,根本不是脚本(如/ etc / fstab).

假设shell脚本以#!/ bin / sh开头.这是一个注释,解释器(shell)忽略#字符后面的所有内容.

#的目的#! line不是为解释器提供信息. #的目的! line是告诉操作系统(或任何进程启动解释器)使用什么作为解释器.

>如果您将脚本作为可执行文件调用,例如,通过运行./script.sh,系统将查询第一行,以查看是否以#!开头,后跟零或多个空格,后跟命令.如果是,则运行该命令,并将脚本名称作为其参数.在此示例中,它运行/ bin / sh script.sh(或技术上,/ bin / sh ./script.sh).
>如果通过显式调用解释器来调用脚本,那么#!从来没有咨询过这条线.因此,如果运行sh script.sh,则第一行无效.如果script2.sh的第一行是#!/usr/games / nibbles,运行sh script2.sh将不会尝试以半字节打开脚本(但是./script2.sh会).

您会注意到,在任何情况下,脚本的扩展名(.sh)(如果有的话)都会影响它的运行方式.在类Unix系统中,这通常不会影响脚本的运行方式.在其他一些系统上,比如Windows,#! shebang line可能被系统完全忽略,扩展可能决定运行脚本的是什么. (这并不意味着您需要提供脚本扩展,但这是原因之一,如果您这样做,它们应该是正确的.)

#!被选中的目的恰恰是因为#开始发表评论. #! line是系统而不是解释器,解释器应该忽略它.

Shebang Line for Bash Scripts

你(最初)说你使用#!/ bin / sh作为bash脚本.只有在脚本不需要任何bash扩展时才应该这样做 – sh需要能够运行脚本. sh并不总是bash的符号链接.通常,包括在所有远程最近的Debian和Ubuntu系统上,sh是一个破折号的符号链接.

Shebang Line for Python Scripts

你还说(在你的问题的第一个版本中,在编辑之前)你用解释器读取#!/ bin / sh来启动你的Python脚本.如果你的意思是字面意思,那么你绝对应该停止这样做.如果hello.py以该行开头,则运行./hello.py执行:

/bin/sh read by the interpretor hello.py

/ bin / sh将尝试执行一个名为read的脚本(由解释器hello.py作为其参数),读取将(希望)找不到,并且Python解释器永远不会看到您的Python脚本.

如果你犯了这个错误但没有我正在描述的问题,你可能通过显式指定解释器(例如,python hello.py)来调用你的Python程序,导致第一行被忽略.当您将脚本分发给其他人,或者很久以后使用它们时,可能不清楚这是否需要它们才能工作.现在最好修复它们.或者至少完全删除第一行,这样当它们无法以./运行时,错误消息才有意义.

对于Python脚本,如果您知道Python解释器的位置(或将要是),您可以编写#!以同样的方式排队:

#!/usr/bin/python

或者,如果它是Python 3脚本,则应该指定python3,因为python is almost always Python 2

#!/usr/bin/python3

但问题是,虽然/ bin / sh应该始终存在,并且/ bin / bash几乎总是存在于bash随操作系统附带的系统上,但Python可能存在于各种各样的地方.

因此,许多Python程序员使用它代替:

#!/usr/bin/env python

(或者#3 /usr/bin/env python3 for Python 3.)

这使得脚本依赖于env在“正确的位置”,而不是依赖于python在正确的位置.这是件好事,因为:

> env几乎总是位于/usr/bin中.
>在大多数系统上,无论运行哪个python脚本都是首先出现在PATH中的脚本.使用#!/usr/bin/env python make ./hello.py启动hello.py运行/usr/bin/env python hello.py,这实际上相当于运行python hello.py.

你不能使用#!python的原因是:

>您希望指定的解释器由绝对路径给出(即以/开头).
>调用进程将在当前目录中执行python.当命令不包含斜杠时搜索路径的行为是特定的shell行为.

有时,Python或其他不是shell脚本的脚本会有一个以#!/ bin / sh …开头的shebang行,其中……是其他一些代码.这有时是正确的,因为有一些方法可以调用带有参数的Bourne兼容shell(sh)来调用Python解释器. (其中一个参数可能包含python.)但是,在大多数情况下,#!/usr/bin/env python更简单,更优雅,更有可能以您想要的方式工作.

Shebang Lines in Other Languages

许多编程和脚本语言以及一些其他文件格式使用#作为注释.对于它们中的任何一个,语言中的文件可以由程序运行,该程序通过在#!之后的第一行指定程序将其作为参数.

在某些编程语言中,#通常不是注释,但作为一种特殊情况,第一行如果以#!开头则被忽略.这便于使用#!语法,即使#不会使一行成为评论.

Shebang为不运行脚本的文件

虽然它不太直观,但任何文件格式都可以容纳以#开头的第一行的文件!其次是可执行文件的完整路径可以有一个shebang行.如果你这样做,并且文件标记为可执行文件,那么你可以像程序一样运行它……使它像文档一样打开.

某些应用程序故意使用此行为.例如,在VMware中,.vmx文件定义虚拟机.您可以“运行”虚拟机,就好像它是一个脚本一样,因为这些文件标记为可执行文件,并且有一个shebang行,导致它们在VMware实用程序中打开.

Shebang为那些不像脚本运行但是像脚本一样的文件

rm删除文件.它不是脚本语言.但是,可以运行启动#!/ bin / rm并标记为可执行文件文件,当您运行它时,会在其上调用rm,将其删除.

这通常被概念化为“文件删除自身”.但该文件根本没有运行.这更像是上面描述的.vmx文件的情况.

不过,因为#! line有助于运行简单命令(包括命令行参数),您可以通过这种方式执行某些脚本.作为比#!/ bin / rm更复杂的“脚本”的简单示例,请考虑:

#!/usr/bin/env tee -a

这会以交互方式接收用户输入,逐行回复用户,并将其附加到“脚本”文件的末尾.

有用?不是特别的.概念上有趣吗?完全!是. (有些.)

概念上类似的编程/脚本概念(只是为了好玩)

>脚本/程序是multiple languages at once,例如,to simulate hashbang functionality in OSes that didn’t have it.

(这些程序被称为polyglots,但这不能与the other sense of polyglot in software development混淆,the other sense of polyglot in software development一个程序/项目,其中不同的部分用不同的语言编写.)
> Metacommands在QBasic / QuickBASIC中,它向编译器(用于编译代码)发出代码生成选项,但是它们是注释的一部分,因此在实际编译/解释期间被忽略.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐