#! 之间是否允许空格?和/bin/bash 在shebang?

Tim*_*Tim 59 shebang

在shebang中,#!和解释器之间是否允许有一个或更多的空间?

例如,#! /bin/bash。看起来可行,但有人说这是不正确的。

ale*_*han 63

是的,这是允许的。

维基百科关于 shebang 的文章 包括 Dennis Ritchie 在 1980 年的一封电子邮件,当时他将 shebang 的内核支持(作为更广泛的称为解释器指令的包的一部分)引入版本 8 Unix(强调我的):

系统已更改,如果正在执行的文件以魔术字符开头,则#!该行的其余部分将被理解为已执行文件的解释器的名称。[…]

为了利用这个绝好的机会,把

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

在 shell 脚本第一行的左边距。 后面!的空白就OK了。

所以shebang之后的空格已经存在了很长一段时间,事实上,丹尼斯·里奇的例子正在使用它们。

请注意,早期版本的 Unix 在此解释器行中限制为 16 个字符,因此您不能在那里有任意数量的空格。此限制不再适用于现代内核。


Eri*_*ouf 43

是的,后面允许有空格#!。甚至(错误地)认为某些系统可能需要它,但它一直只是可选的。

如需进一步阅读,请尝试这里


Luk*_*ger 8

仅供参考,某些版本的 systemd 无法解析带有空格的 shebang。使用这样的服务:

[Service]
Type=oneshot
ExecStart=/root/foo.sh
Run Code Online (Sandbox Code Playgroud)

...和这样的shebang:

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

...你可能会收到这样的错误:

systemd[32834]: foo.service: Failed at step EXEC spawning /root/foo.sh: Exec format error
Run Code Online (Sandbox Code Playgroud)

从 shebang 中删除空间修复了错误。所以要注意那个。

  • FWIW,我无法使用 systemd 245.4-4ubuntu3.6(在 Ubuntu 20.04 上)进行复制。 (3认同)
  • 我不确定为什么 systemd 想要自己解析 shebangs。另外,如果 systemd 尝试执行“/bin/bash”而不是“/bin/bash”,我预计会出现“没有这样的文件或目录”错误。这一切都表明 systemd 没问题,但你的问题在其他地方。也许您的“#!”开头有一个 UTF-8 BOM /bin/bash` 脚本? (3认同)
  • 啊。我对 systemd 脾气暴躁的另一个原因;正是我需要的……感谢您的提醒。 (2认同)
  • 我在 systemd 的源代码中找到的对 `shebang` 的唯一引用是在 `./test/test-functions` 中关于 `_shebang_regex='(#! *)(/[^ ]+).*'`(来自不知道 bash regexp 显然没有锚定的人)明确允许这些空间(但与执行服务没有其他关系)。 (2认同)