> The -S option allows specifing [sic] multiple parameters in a script.
> [...]
> Without the '-S' parameter the script will likely fail with:
> . . . /usr/bin/env: 'perl -w -T': No such file or directory
I actually ran into this problem last week and just used the absolute path with an argument (/usr/bin/python3 -u) instead of passing an argument to env, and I added a TODO comment to figure out how to do this better. Now you made me find the right way :)
In TXR Lisp, I invented a novel way of doing this, which I call the "hash bang null hack".
If you put a NUL character into the hash bang line, then TXR will process arguments after that character. The NUL character is a string terminator, and so the operating system kernel doesn't see it; it thinks that's the end of the hash bang line.
So for instance (^@ represents NUL):
#!/usr/bin/env txr^@arg arg arg
This hack is not necessary, of course; a given language interpreter can do this in any number of ways. E.g. arguments in a comment in the following line. The convention could be, say, that if the next line also starts with #!, it holds parameters:
#!/usr/bin/env my-language
#!--args to my language
I didn't do it this way because the language doesn't use # comments (so hacking argument recognition into comment processing is out) and I didn't want to complicate the hash bang logic to dealing with two or more lines: everything is handled in the one line and that's it.Another solution is to rely on env having the BSD -S option, which specifies a string that becomes multiple arguments.
#!/usr/bin/env -S program --option arg
the hash bang mechanism will pass "program --option arg" as a single argument to env, whose -S option will split that into multiple arguments. You might run into a limit on the hash bang header. E.g. if the given operating system reads only, say, 32 bytses of the file (really ancient Unix system), in which it looks for the hash bang line, then you have only that much space to cram into that -S argument.The -S option implemented in BSD unixes has a lot of bells and whistles: you can use escape characters in it to encode control characters and $ to expand environment variables. E.g. silly example:
#!/usr/bin/env -S $USER/bin/interp
would use every user's own "interp" in their own bin directory to run the program.-S is not portable; it's not specified in POSIX. Newer versions of GNU Coreutils have it (but not with all the BSD features, I think). If you maintain a programing language, it behooves you to solve this problem for the users, so the only nonstandard thing they rely on is your language, without any collateral nonstandard stuff.
#!/usr/bin/env bash
set -eu
# Your script here