sbang lets you run scripts with very long shebang (
Many operating systems limit the length and number of possible arguments in shebang lines, making it hard to use interpreters that are deep in the directory hierarchy or require special arguments.
To use, put the long shebang on the second line of your script, and make sbang the interpreter, like this:
#!/bin/sh /path/to/sbang #!/long/path/to/real/interpreter with many arguments
sbang will run the real interpreter with the script as its argument.
Most people don't have long shebang problems. They can come up if you install software in deeply nested directories. e.g., in your home directory (with something like Spack), or in a shared project directory on an NFS volume. It also comes up in deeply nested virtual environments, where the
python interpreter is copied into a deep path.
sbang is useful for user-installed code. Admins who have root and can put software wherever they want will likely not need it.
Suppose you have a script,
long-shebang.sh, like this:
#!/very/very/long/path/to/some/interp echo "success!"
very/long/path is actually very long, running this script will result in an error on some OS's. On Linux, you get an error this:
$ ./long-shebang.sh -bash: ./long=shebang.sh: /very/very/long/path/to/some/interp: bad interpreter: No such file or directory
On macOS, things are worse. The system doesn't consider the long interpreter path, and just tries to run the script with the shell. This is not likely to be what you intended.
Shebangs with arguments
Passing arguments on the shebang line is an issue. Consider:
#!/path/to/interp -a -b -c ...
Depending on your OS,
interp may end up receiving a single argument like
"-a -b -c" instead of three separate arguments (
sbang will delegate shebang arguments separately, as you would expect, so you can do this:
#!/bin/sh /path/to/sbang #!/path/to/interp -a -b -c ...
There's a really comprehensive writeup on the history and limitations of the shebang mechanism at https://www.in-ulm.de/~mascheck/various/shebang/.
You can use
sbang in several ways.
sbang on the command line
You can use
sbang in two ways. You can use it directly, from the command line, like this:
$ sbang ./long-shebang.sh success!
sbang as the interpreter
You can also use
sbang as the interpreter for your script. Put
#!/bin/sh /path/to/sbang on line 1, and move the original shebang to line 2 of the script:
#!/bin/sh /path/to/sbang #!/long/path/to/real/interpreter with arguments echo "success!"
$ ./long-shebang.sh success!
On Linux, you could shorten line 1 to
#!/path/to/sbang, but other operating systems like Mac OS X require the interpreter to be a binary, so it's best to use
sbang as an argument to
/bin/sh. Obviously, for this to work,
sbang needs to have a short enough path that it will run without hitting OS limits.
Other comment syntaxes
For Lua, node, and php scripts, the second line can't start with
# is not the comment character in these languages (though they all ignore
#! on the first line of a script). Instrument such scripts like this, using
<?php ... ?> instead of
# on the second line, e.g.:
#!/bin/sh /path/to/sbang --!/long/path/to/lua with arguments print "success!"
#!/bin/sh /path/to/sbang //!/long/path/to/node with arguments print "success!"
#!/bin/sh /path/to/sbang <?php #/long/path/to/php with arguments ?> <?php echo "success!\n"; ?>
How it works
sbang is a very simple POSIX shell script. It looks at the first two lines of a script argument and runs the last line starting with
#!, with the script as an argument. It also forwards arguments. Because it's simple POSIX, you can use it almost anywhere.
sbang is distributed under the terms of both the MIT license and the Apache License (Version 2.0). Users may choose either license, at their option.
All new contributions must be made under both the MIT and Apache-2.0 licenses.
SPDX-License-Identifier: (Apache-2.0 OR MIT)