为什么.sh文件的第一行注释是必要的?

为什么.sh文件的第一行注释是必要的?

有人告诉我,#!/bin/bashshell 脚本文件中的第一行 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/bashthen ,这样它将在 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

相关内容