diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2016-03-05 04:18:48 -0800 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2016-03-05 04:18:48 -0800 |
commit | fc6aa7374a243928af38fd1e583c6c67146951cd (patch) | |
tree | 22bb8eba191bd22d62a59cf4960def42ffe545bf /bin | |
parent | 8d2538f205ba9d9d9f0cafd678f500de04a6f144 (diff) | |
download | spack-fc6aa7374a243928af38fd1e583c6c67146951cd.tar.gz spack-fc6aa7374a243928af38fd1e583c6c67146951cd.tar.bz2 spack-fc6aa7374a243928af38fd1e583c6c67146951cd.tar.xz spack-fc6aa7374a243928af38fd1e583c6c67146951cd.zip |
Fix #104, #54: issues with overlong shebang in deep directories.
This does several things:
- Add `sbang`: a script to run scripts with long shebang lines.
- Documentation for `sbang` is in `bin/sbang`.
- Add an `sbang` hook that filters the `bin` directory after install
and modifies any scripts wtih shebangs that are too long to use
`sbang` instead.
- `sbang` is at the top level, so it should be runnable (not much we
can do if spack itself is too deep for shebang)
- `sbang`, when used as the interpreter, runs the *second* shebang
line it finds in a script.
- shoud fix issues with too long shebang paths.
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/sbang | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/bin/sbang b/bin/sbang new file mode 100755 index 0000000000..ebfbe2e7a1 --- /dev/null +++ b/bin/sbang @@ -0,0 +1,84 @@ +#!/bin/bash +# +# `sbang`: Run scripts with long shebang lines. +# +# Many operating systems limit the length of shebang lines, making it +# hard to use interpreters that are deep in the directory hierarchy. +# `sbang` can run such scripts, either as a shebang interpreter, or +# directly on the command line. +# +# Usage +# ----------------------------- +# Suppose you have a script, long-shebang.sh, like this: +# +# 1 #!/very/long/path/to/some/interpreter +# 2 +# 3 echo "success!" +# +# Invoking this script will result in an error on some OS's. On +# Linux, you get this: +# +# $ ./long-shebang.sh +# -bash: ./long: /very/long/path/to/some/interp: bad interpreter: +# No such file or directory +# +# On Mac OS X, the system simply assumes the interpreter is the shell +# and tries to run with it, which is likely not what you want. +# +# +# `sbang` on the command line +# ----------------------------- +# You can use `sbang` in two ways. The first is to 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/bash /path/to/sbang` on line 1, and move the original +# shebang to line 2 of the script: +# +# 1 #!/bin/bash /path/to/sbang +# 2 #!/long/path/to/real/interpreter with arguments +# 3 +# 4 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 a `bash` argument. +# Obviously, for this to work, `sbang` needs to have a short enough +# path that *it* will run without hitting OS limits. +# +# +# How it works +# ----------------------------- +# `sbang` is a very simple bash 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. +# + +# First argument is the script we want to actually run. +script="$1" + +# Search the first two lines of script for interpreters. +lines=0 +while read line && ((lines < 2)) ; do + if [[ "$line" = '#!'* ]]; then + interpreter="${line#\#!}" + fi + lines=$((lines+1)) +done < "$script" + +# Invoke any interpreter found, or raise an error if none was found. +if [ -n "$interpreter" ]; then + exec $interpreter "$@" +else + echo "error: sbang found no interpreter in $script" + exit 1 +fi |