Shebang
- The bible of shebang interpretations:
The
#!
magic, details about the shebang/hash-bang mechanism on various Unix flavours
1. Splitting arguments
According to Shebang Shenanigans and section splitting arguments, when it comes to multiple arguments after shebang, different systems interpret then differently. For example:
#!/usr/local/bin/args -a -b --something
Linux treats -a -b --something
as a single argument. MacOS treats
them as 3 separate arguments. Some other systems may even pass -a
as
a single argument and discard the rest.
Also, from this article, in the bash document:
If the program is a file beginning with
#!
, the remainder of the first line specifies an interpreter for the program. … The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the program, followed by the name of the program, followed by the command arguments, if any.
Note here, a single optional argument.
1.1. env -S
to the rescue
According to this answer, starting with coreutils 8.30, you can use:
#!/usr/bin/env -S command arg1 arg2 ...
The -S/--split-string
option enables use of multiple arguments in
shebang.
1.2. An example
First, write a simple Python script for displaying arguments:
#!/usr/bin/env python import sys for i, arg in enumerate(sys.argv): print(f"{i}: {arg}")
Store it under /tmp/showargs
and make it executable.
Test the script:
$ /tmp/showargs single 'one long arg' another single
0: /tmp/showargs
1: single
2: one long arg
3: another
4: single
If the shebang calls showargs
directly, the arguments are merged into
one:
$ cat go #!/tmp/showargs single 'one long arg' another single $ ./go 0: /tmp/showargs 1: single 'one long arg' another single 2: ./go
However, using env -S
solves this problem:
$ cat go #!/usr/bin/env -S /tmp/showargs single 'one long arg' another single $ ./go 0: /tmp/showargs 1: single 2: one long arg 3: another 4: single 5: ./go