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)?

Asked By: jrw32982

||

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 see binfmt_script.c which contains the important parts.
Linux allows at most BINPRM_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.

Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.