4 ms·
In Spack https://github.com/spack/spack https://github.com/spack/spack), we encounter this when users install packages in deep paths within their home directori
by tgamblin 6y ago
In Spack https://github.com/spack/spack https://github.com/spack/spack), we encounter this when users install packages in deep paths within their home directories, or in deep paths within shared project directories (e.g., in NFS or Lustre on HPC machines). So we patch installed scripts that have long shebangs.
We want installed packages to work exactly as built, with the right versions of dependencies, and we don't want to rely on the user getting their environment right to do that. Spack users may install several versions of python or other interpreters. This ensures that scripts work without a special environment.
There is another use case that is less emphasized here. sbang also lets you pass arbitrarily many arguments on the shebang line. If you do this:
#!/usr/bin/perl arg1 arg2 arg3
At least on Linux, you'll get one argument: "arg1 arg2 arg3". I think perl gets around this by parsing the shebang line itself, but sbang is more general. You can use it with /usr/bin/env to pass more arguments than would otherwise be allowed.
See https://www.in-ulm.de/~mascheck/various/shebang/ https://www.in-ulm.de/~mascheck/various/shebang/ for an extremely comprehensive list of limitations on shebangs.
- toomuchtodo 6y agoThanks for sharing this. Wish I had this years ago at an HPC gig at FNAL (similar use case, with users having deep path home directories on Lustre and pNFS).
- shakna 6y ago> There is another use case that is less emphasized here. sbang also lets you pass arbitrarily many arguments on the shebang line. If you do this: Most often when calling programs with a shell script it is recommended to make use of env to find it. Like... #!/usr/bin/env python3 As in the limitations link above, env is pretty much everywhere, and when it isn't, you're probably going to struggle anyway to make anything portable to those systems. env actually has an in-built flag for ensuring you're passing arguments. #!/usr/bin/env -S python3 -m http.server 8010
- tgamblin 6y agoTrue. The two disadvantages are: - you still get the python3 in PATH, not a specific one (sbang aims to use a specific interpreter) - The -S argument to env is not POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html https://pubs.opengroup.org/onlinepubs/9699919799/utilities/e...
- shakna 6y ago> you still get the python3 in PATH, not a specific one (sbang aims to use a specific interpreter) env lets you solve that one too. You can control PATH. From the FreeBSD manpages: #!/usr/bin/env -S -P/usr/local/bin:/usr/bin perl And if you lack the -P flag... env controls the environment variables... So, you could extend (or replace) it like so: #!/usr/bin/env PATH=/home/my/loc:${PATH} perl > The -S argument to env is not POSIX You're right. POSIX only guarantees the -i flag, and the ability to set variables. It hasn't been modified in the standard since 1991, despite other updates to the standard. OpenBSD and Busybox only supports the crippled POSIX version. It isn't completely portable. Versions with -S and are available on Linux, FreeBSD (also has -P), macOS (also has -P).
- tgamblin 6y agoYeah it would be nice if POSIX would move a little faster, but I guess the slowness is the point. This is probably obvious but bears repeating since we're on this tangent -- even -S and -P do not prevent the OS from truncating the shebang if it's too long. So env is great for passing multiple args, but it still doesn't let you use really long shebangs (the original point of the thread :)
- sdflhasjd 6y agoSlightly off-topic, but are you aware that "spack" is a common derogatory slur in British English?
- shawnz 6y agoWhy not just output a wrapper script? That seems to achieve the same thing while adhering better to the principal of least surprise