Git Product home page Git Product logo

sbang's Introduction

sbang

linux macos shellcheck codecov

sbang lets you run scripts with very long shebang (#!) lines.

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.

Why?

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.

Generally, sbang is useful for user-installed code. Admins who have root and can put software wherever they want will likely not need it.

Long shebangs

Suppose you have a script, long-shebang.sh, like this:

#!/very/very/long/path/to/some/interp

echo "success!"

If 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 ("-a", "-b", "-c"). 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

...

Further reading

There's a really comprehensive writeup on the history and limitations of the shebang mechanism at https://www.in-ulm.de/~mascheck/various/shebang/.

Using sbang

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 #!, as # 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 --, //, or <?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.

Authors

sbang was created by Todd Gamblin, [email protected], as part of Spack.

Related projects

The long-shebang project is like sbang but written in C instead of POSIX sh. It grew out of Nix a few months after sbang grew out of Spack, for similar reasons.

License

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.

See LICENSE-MIT, LICENSE-APACHE, COPYRIGHT, and NOTICE for details.

SPDX-License-Identifier: (Apache-2.0 OR MIT)

LLNL-CODE-816912

sbang's People

Contributors

healther avatar luigi-calori avatar michaelkuhn avatar muffgaga avatar tgamblin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbang's Issues

filter_shebang fails on non UTF-8 script

Some typically European (Continental) scripts are in some variant of ISO-8859 which python knows as latin-1.
filter_shebang demands an UTF-8 input file so it fails for these scripts.
This is the case on package perl-tk with a copyright (©) character in ptked (Nick Ing-Simmons Copyright).
I made a proposal for modification in spack with PR 24263. It also traps some old Asian encoding.
I report this here following Massimiliano advise.

Helping user scripts use `bin/sbang`

In a recent PR I pontificated about the importance of hardwiring the sbang line so that scripts use the interpreter with which they were built.

In the ongoing discussion about LD_LIBRARY_PATH I've learned that it's important to help "user-space" people use Spack-managed trees to build their own software.

Today I helped a "user-space" someone use the perl and cpanm from one of my test trees to install a CPAN-style distro, only to discover that the resulting sbang line in the distro's scripts was too long. (First we rediscovered spack/spack#4338, but that's fixed). My production trees have paths that squeak in under the line, phew.

Does anyone have any experience with helping "user-space" people use Spacks sbang-ification tools? Documentation about how they might use Spack sbanging code?

It seems as if one could write a fairly short script that accepted a directory name, imported the bits from lib/spack/spack/hooks/sbang.py and then called filter_shebangs_in_directory on it.

Perhaps I should write one and PR it to live in the bin directory alongside the spack command?

Is there a better solution?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.