Shebang can reference a script in Linux
I’ve always heard that the target of a shebang line (e.g. #!/bin/bash
) must be a binary executable, not a script. And this is still true for many OSes (e.g. MacOS). But I was surprised to see that this is not true on Linux, where up to 4 levels of scripts can be used, where the fourth script references a binary executable in its shebang line. However, if 5 levels of scripts are used, then the program will fail with the error Too many levels of symbolic links
.
See the LWN article "How programs get run" and the following code which was not shown in that article.
$ cat wrapper2
#!./wrapper
When did this change occur (assuming that at some point it was not allowed)?
According to Sven Mascheck (who’s generally reliable and well-informed):
interpreter itself as
#!
script
or: can you nest#!
?(…)
Linux since 2.6.27.9 2 and Minix accept this.(…)
see the kernel patch
(patch to be applied to 2.6.27.9) and especially seebinfmt_script.c
which contains the important parts.
Linux allows at mostBINPRM_MAX_RECURSION
, that is 4, levels of nesting.
Note that this recursion concerns both indirect execution mechanisms that Linux implements: #!
scripts, and executable formats registered through binfmt_misc. So for example you can have a script with a #!
line that points to an interpreter written in bytecode which gets dispatched to a foreign-architecture binary which gets dispatched via Qemu, and that counts for 3 levels of nesting.
Sven Mascheck also notes that no BSD supports nested shebang, but that some shells will take over if the kernel returns an error.