没有shebang线的shell脚本工作正常吗?为什么?

27 unix linux bash shell perl

我写了一个简单的shell脚本,发现我的shell脚本不需要shebang line

#!/bin/sh
Run Code Online (Sandbox Code Playgroud)

如果我给我的脚本执行权限并执行使用./myscript.sh.它运行正常.

我正在使用bashshell,/bin/sh实际上是指向bash.

lrwxrwxrwx 1 root root /bin/sh -> bash
Run Code Online (Sandbox Code Playgroud)

我知道shebang line用于告诉shell哪个解释器用于你的其余脚本.

如果我想念perl中的shebang行,给予执行权限并运行./myscript.pl,它不起作用.

这里到底发生了什么?如果我使用./,什么时候需要shebang线呢?

Ala*_*rry 18

您输入的父shell ./myscript.sh首先尝试使用execve它,这是shebang行生效的地方.当这工作时,父级不知道脚本和ELF之间的区别,因为内核会处理它.

execve失败,让一个古老的UNIX兼容的功能,比罗马的家当线的存在,被激活.它猜测一个具有执行权限但内核无法识别为有效可执行文件的文件必须是shell脚本.

通常,父shell猜测脚本是为同一个shell编写的(最小的Bourne-like shell运行脚本/bin/sh,bash将其作为bash子进程运行), csh根据第一个字符做一些更复杂的猜测,因为它早于shebang它也需要与Bourne shell共存).

当你知道这些猜测是错误的时候(例如,使用shebang #!/usr/bin/perl),或者你不相信猜测一致地工作,或者当脚本需要由不是父进程运行时,你需要一个shebang线一个shell本身.

  • 更多信息可以在对 *Why do some scripts start with #! 的回答中找到。... ?* 问题在 http://www.faqs.org/faqs/unix-faq/faq/part3/section-16.html (3认同)

Mic*_*ker 14

文件中需要shebang行,并且只有当它意味着作为可执行文件运行时(与sh file.sh调用相反.脚本实际上不需要它,系统知道如何查找解释器).

编辑:很抱歉误读了这个问题.如果使用shebang线丢失或未识别,/bin/sh则使用.但我更喜欢明确解释翻译.

注意,这种行为不是通用的,IIRC,只有一些exec*家庭功能这样做(更不用说不同的平台),所以这是明确的另一个原因.

  • *如果shebang线丢失或无法识别,则使用`/ bin/sh`.*由什么使用; shell,内核,别的什么?使用`/ bin/sh`是因为脚本的扩展是`sh`还是没关系?这个答案严重缺乏. (6认同)
  • OP说他将脚本调用为`./ myscript.sh` - 我认为这意味着他没有明确地使用shell作为可执行文件和脚本作为参数. (2认同)

cda*_*rke 5

POSIX(单一 UNIX 规范 4)标准没有帮助:

如果 shell 命令文件的第一行以字符“#!”开头 ,结果未指定。

因此,该标准意味着如果您没有 #! 那么它应该运行 POSIX shell。但现代 shell 不符合 POSIX 标准。旧的 Korn Shell 88 (ksh88) 运行 Bourne shell(接近 POSIX shell),没有 #! 线,但 ksh93 打破了这一点,Bash 也是如此。对于 ksh93 和 Bash,如果没有 #!,它们会运行自己的 shell。线存在。

尽管流行观点不同,Bash 和 Korn shell 仍然有所不同。当您编写 shell 脚本时,您永远无法确定将从哪个 shell 运行,或者即使它将从另一个 shell 运行(大多数编程语言都可以运行其他程序)。一旦你使用 Bourne/POSIX 语法之外的东西,你就会陷入困境。

始终使用#!线,不要让它碰运气。

  • 您关于壳牌合规性的声明被颠倒了。像 ksh 和 bash 这样的现代 shell 符合 POSIX 标准(或者至少非常接近),而 Bourne shell 绝对不符合。shell 的最初 POSIX 标准本质上是 ksh88。当标准规定应使用 POSIX 兼容 shell 时,这使得 bash 和 ksh 自行运行是合理的。Bash、ksh88 和 ksh93 肯定有所不同,但它们所做的区域要么是标准中未指定的行为,要么超出了其范围。 (2认同)
  • `如果 shell 命令文件的第一行以字符“#!”开头 ,结果未指定。`我将其读为“如果“#!” 然后未指定。`,但你的其余答案表明相反(“如果没有“#!”存在,则未指定。”)。你是不是漏掉了一个否定句?否则,您能否解释*在什么情况下* **是** *结果* **指定**? (2认同)