我一直听说 shebang 行(例如#!/bin/bash
)的目标必须是二进制可执行文件,而不是脚本。对于许多操作系统(例如 MacOS)来说仍然如此。但令我惊讶的是,在 Linux 上情况并非如此,Linux 上最多可以使用 4 级脚本,其中第四个脚本在其 shebang 行中引用了二进制可执行文件。但是,如果使用 5 级脚本,则程序将失败并出现错误Too many levels of symbolic links
。
请参阅LWN 文章“程序如何运行”以及该文章中未显示的以下代码。
$ cat wrapper2
#!./wrapper
此更改何时发生(假设在某些时候不允许)?
答案1
根据斯文·马斯切克(通常可靠且消息灵通):
解释器本身作为
#!
脚本或者:你可以嵌套吗#!
?(…)
Linux 自 2.6.27.9 2 起和 Minix 接受这一点。(……)
看到内核补丁 (补丁适用于 2.6.27.9),特别参见
binfmt_script.c
其中包含重要部分。 Linux 最多允许BINPRM_MAX_RECURSION
4 层嵌套。
请注意,此递归涉及 Linux 实现的间接执行机制:#!
脚本和通过 binfmt_misc 注册的可执行格式。例如,您可以有一个脚本,其中一行#!
指向用字节码编写的解释器,该解释器被分派到外部架构二进制文件,该二进制文件通过 Qemu 分派,并且计为 3 层嵌套。
Sven Mascheck 还指出,没有 BSD 支持嵌套 shebang,但如果内核返回错误,某些 shell 将接管。