#!
- Some details about the shebang mechanism on various Unix
flavoursHere you'll find:
So this mechanism was invented between version7 and version8. It was also available in 4BSD (probably not activated in the Makefile until 4.3), but not yet in 3BSD.
(Pointed out by Gunnar Ritter in <3B5B0BA4.XY112IX2@bigfoot.de> in de.comp.os.unix.shell.)
#!/usr/bin/env perl
".
However, env(1) is not /usr/bin/env but /bin/env on some Linux distributions. So the env-mechanism is increasing convenience, but not really improving portability.
#! /
" as a 32-bit (long) magic.
But it turns out that it is impossible to find a Unix which actually requires this.
4.2BSD in fact doesn't, although the GNU autoconf tutorial wrongly claims this (5.5: Portable Shell Programming).
But instead, see the 4.2BSD source: sys/kern_exec.c, (mainly l.123 ff.). It (certainly) accepts, but doesn't require a blank.
(All this pointed out by Gunnar Ritter in <3B5B0BA4.XY112IX2@bigfoot.de> in de.comp.os.unix.shell.)
sizeof(struct a.out)
".
The reason is a union, which contains both struct a.out/exec
and a string with the same length (to access the shebang line).
(For probably very similar code see also e.g. 4.3BSD sys/kern_exec.c)
Shell Introduction [...] If the first line of a file of shell commands starts with the characters #!, the results are unspecified. The construct #! is reserved for implementations wishing to provide that extension. A portable application cannot use #! as the first line of a shell script; it might not be interpreted as a comment. [...] Command Search and Execution [...] This description requires that the shell can execute shell scripts directly, even if the underlying system does not support the common #! interpreter convention. That is, if file foo contains shell commands and is executable, the following will execute foo: ./foo
Well, speaking about "#!/bin/sh", this is a really rocksolid convention, if you accept anything from the Bourne Shell family and its descendants to be called.
I was using the following as program "showargs":
#include <stdio.h> int main(int argc, char** argv) { int i; for (i=0; i<argc; i++) fprintf(stdout, "argv[%d]: \"%s\"\n", i, argv[i]); return(0); }
and a one liner script "invoker.sh" to call it, similar to
#!/tmp/showargs -1 -2 -3
to produce the following results (tried them myself, but i'd like to add your results from yet different systems).
Typically, a result from the above would look like this:
argv[0]: "/tmp/showargs" argv[1]: "-1 -2 -3" argv[2]: "./invoker.sh"...but the following table lists the variations, the meaning of the columns is explained below.
| maximum |cut-off(c)|only the|each arg|invoker in|not full | length of|error(err)|1st arg |in its |argv[0] |path in | shebang- |or ENOEXEC| |own | (not the |argv[0] | line: |( ) [1]| |argv[x] | invoked)| ------------------+----------+----------+--------+--------+----------+------- AIX 3.2.5 | > 80 | [2] | | | | [2] AIX 4.3.2 | > 80 | | | | | X FreeBSD 4.3(alpha)| 64 | | | X | | FreeBSD 4.5(alpha)| > 80 | err | | X | | HP-UX A.08.07 | 32 | | | | X | - HP-UX B.09.03 | 32 | | | | X | - HP-UX B.10.10 | > 80 | [3] | | | | [3] HP-UX B.10.20 | > 80 | | | | | IRIX 5.3 | > 80 | err | | | | IRIX 6.5 | > 80 | err | | | | Linux 2.2.9 (x86) | > 80 | c | | | | X MUNIX 3.1 (SVR3.x)| 32 | | | | X | NetBSD 1.5(alpha) | 64 | | | | | OpenBSD 2.9 | 64 | | | | | OSF1 V4.0(alpha) | > 80 | | | | | X OSF1 T5.1(alpha) | > 80 | | | | | X Sinix 5.20 | 32 | | | | | SunOS 4.1.4(sparc)| 32 | c | | | | SunOS 5.x(sparc) | > 80 | | X | | | Ultrix 4.5 | 80 | ? | X | | |
Meaning of the columns:
argv[1]
from above contains
"-1
" then
argv[1]:"-1",
argv[2]:"-2"
, etc.
argv[0]
doesn't contain
"/tmp/showargs
" but "./invoker.sh
"
argv[0]
contains
the basename of the called program instead of its full path.
Footnotes in the table:
[1] | If the shebang line is too long, three things can happen:
|
[2] | If the shebang line exceeds 255 characters, it gets cut down to exactly 80 characters--or the first argument, if this is shorter. If the shebang line was not too long, argv[0] is the basename of the invoked program, otherwise the absolute path. |
[3] | If the shebang line exceeds 128 characters, it gets cut down to exactly 80 characters--or the first argument, if this is shorter. If the shebang line was not too long, argv[0] is the invoking, otherwise the invoked program. |
And why shebang? In music, '#' means sharp. So just shorten it to sharp-bang. Or it might be derived from "shell bang". All this probably under the influence of the american slang idiom "the whole shebang" (everything, the works). See also the jargon dictionary for the latter explanation.