shell 脚本在没有#!(sha-bang 行)的情况下仍然可以工作

shell 脚本在没有#!(sha-bang 行)的情况下仍然可以工作

我是 shell 脚本的新手,很多书都写过在脚本开头使用 #!(sha-bang) 行来调用解释器。这将为脚本调用一个新的 shell 并逐行进行解释。但是我的基本脚本仍在运行,没有魔法线。

所以我的问题是:

  • 我的基本脚本从哪里得到解释器。
  • 脚本是如何找到解释器的?

现在让我告诉你我的基本脚本它只包含以下行:

echo“没有魔法线的基本脚本”

答案1

当你执行一个程序时,内核会检查它是否由某些程序启动魔术字节序列。如果可执行文件以 开头#!,则内核将该行的其余部分解释为解释器名称。如果可执行文件以\177ELF(其中\177字节 127)开头,则它将文件加载为极低频可执行文件;这是当今大多数 UNIX 系统上的正常类型。

如果内核无法识别该文件格式,它将拒绝执行该文件并返回错误ENOEXEC(执行格式错误)。当 shell 注意到这一点时,它会自行将程序作为 shell 脚本执行。

要见证这一点,请在脚本中添加一些命令:

ps l $$
ls -l /proc/$$/exe
echo hello

(这是针对 Linux 的,请针对其他 unice 进行调整。)然后尝试从各种 shell 运行该脚本。您将看到一些 shell 生成自己的新实例来执行脚本(bash、ksh93),而其他 shell 生成/bin/sh(dash、pdksh、zsh)。

答案2

如果未提供 magic line,则使用默认 shell 来运行脚本。这个默认 shell 可以是 Bourne shell (sh),在某些风格中就是这种情况,但是,在其他一些风格中,使用的默认 shell 与执行它的登录 shell 相同。问题是:不要让系统来决定 shell,始终在第一行提供您想要的 shell。

答案3

可能是以下3种可能性之一:

  1. 您正在使用解释器直接调用脚本,IE:bash script.sh

  2. 脚本文件的名称具有 .sh 扩展名,它使系统查找此类文件的默认程序

  3. 您使用的 shell 环境正在自行执行“echo”,因为我只能猜测脚本文件是可执行的。例如,如果您将使用 bash shell,并且文件中有一个仅由 ksh 使用的命令,那么您会发现它不起作用。

祝你好运!

相关内容