![为什么.sh文件的第一行注释是必要的?](https://linux22.com/image/45411/%E4%B8%BA%E4%BB%80%E4%B9%88.sh%E6%96%87%E4%BB%B6%E7%9A%84%E7%AC%AC%E4%B8%80%E8%A1%8C%E6%B3%A8%E9%87%8A%E6%98%AF%E5%BF%85%E8%A6%81%E7%9A%84%EF%BC%9F%20.png)
有人告诉我,#!/bin/bash
shell 脚本文件中的第一行 shebang ( ) 是必需的,如果没有这一行,文件将无法准确运行。但我测试了一些脚本。没有那条线他们工作得很好。
这行只是一条注释吗? bash 是否像其他注释一样省略了这一行?或者 bash 会解释它吗?
该行是否强制采用该格式?或者只是一个有用的可读注释?如果我用其他方式来表达,比如说,不带 呢!
?
答案1
内核1本身对此是清楚的。 shebang 一定在那儿;否则内核不会认为这样的文件是可执行文件(脚本)。
在 Linux 中,exec
系统调用(又名execve
)调用以下代码 linux/fs/binfmt_script.c
。
static int load_script(struct linux_binprm *bprm)
{
[...]
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
return -ENOEXEC;
但是,如果 shebang 丢失,shell 可能会选择自己执行该文件。看 当开头没有 shebang 行 ( ) 时,哪个 shell 会执行脚本?#!/path/to/shell
所以它似乎适用于 shell 脚本,但它不是您应该依赖的功能。
但是,如果您的 shell 脚本使用 bashisms 该怎么办?您必须有#!/bin/bash
then ,这样它将在 bash 而不是其他 shell 中执行。同样,如果尝试执行它的程序本身不是 shell,它也会被执行。还有完全不同语言的脚本,例如 Perl 或 Python。如果没有 shebang,系统将不知道要使用哪个解释器来完成这些任务。
______________
1 这是一个 Unix 功能方式早于 Linux;看舍邦历史。
答案2
这舍邦告诉内核执行脚本时调用哪个程序直接地。
chmod +x myscript.sh
./myscript.sh
答案3
仅当满足以下条件之一时才需要 shebang:
您的脚本是不可移植的,即使用 POSIX 标准不支持的内容(例如:bashisms、kshisms 或其他),因此需要指定应启动哪个解释器。这显然包括外来脚本语言(csh、perl、python...)。由于您的问题是关于
#!/bin/bash
,您很可能属于这种情况。您正在非 POSIX 环境/模式下运行脚本。
否则,shebang 不是必需的,甚至实际上不建议用于严格遵守 shell 脚本。原因是尽管普遍认为,但/bin/sh
它不一定是 POSIX shell 的默认路径。检索标准 shell 位置的唯一受支持的方法是运行
PATH=`getconf PATH` command -v sh
POSIX 标准状态:
如果 shell 命令文件的第一行以字符“#!”开头,则结果未指定。
答案4
作为补充frostschutz 的回答,某些 shell 能够解释 hash bang (shebang) 行。 Bash 通常仅在内核不支持 hash bang 解释时才启用此功能。
但是,如果您希望使用 shebangs 行,在 Bash 源代码中使用它们可能比在内核源代码中更容易。
从bash/execute_cmd.c
:
#if !defined (HAVE_HASH_BANG_EXEC)
if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
return (execute_shell_script (sample, sample_len, command, args, env));
else
#endif
从bash/config.h
:
/* Define if the kernel can exec files beginning with #! */
#define HAVE_HASH_BANG_EXEC 1