sbang: vendor sbang
`sbang` now lives at https://github.com/spack/sbang, and it has its own test suite that's more extensive than what's in Spack. We'll leave sbang tests to sbang from now on, and just vendor `bin/sbang` directly. Remaining `sbang` tests have to do with patching files, not with `sbang`'s functionality. This update also fixes a bug with `sbang` and multiple command line arguments that was introduced in #19529. See: * https://github.com/spack/sbang/pull/1 * https://github.com/spack/sbang/pull/2 - [x] include latest `sbang` from https://github.com/spack/sbang - [x] remove old `sbang` tests from Spack - [x] update `COPYRIGHT` and `cmd/license.py`
This commit is contained in:
		
							
								
								
									
										110
									
								
								bin/sbang
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								bin/sbang
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| #!/bin/sh | ||||
| # | ||||
| # Copyright 2013-2020 Lawrence Livermore National Security, LLC and other | ||||
| # Spack Project Developers. See the top-level COPYRIGHT file for details. | ||||
| # sbang project developers. See the top-level COPYRIGHT file for details. | ||||
| # | ||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||
|  | ||||
| @@ -12,85 +12,16 @@ | ||||
| # arguments in shebang lines, making it hard to use interpreters that are | ||||
| # deep in the directory hierarchy or require special arguments. | ||||
| # | ||||
| # `sbang` can run such scripts, either as a shebang interpreter, or | ||||
| # directly on the command line. | ||||
| # To use, put the long shebang on the second line of your script, and | ||||
| # make sbang the interpreter, like this: | ||||
| # | ||||
| # Usage | ||||
| # ----- | ||||
| # Suppose you have a script, long-shebang.sh, like this: | ||||
| #     #!/bin/sh /path/to/sbang | ||||
| #     #!/long/path/to/real/interpreter with arguments | ||||
| # | ||||
| #     1    #!/very/long/path/to/some/interp | ||||
| #     2 | ||||
| #     3    echo "success!" | ||||
| # `sbang` will run the real interpreter with the script as its argument. | ||||
| # | ||||
| # Invoking this script will result in an error on some OS's.  On | ||||
| # Linux, you get this: | ||||
| # See https://github.com/spack/sbang for more details. | ||||
| # | ||||
| #     $ ./longshebang.sh | ||||
| #     -bash: ./longshebang.sh: /very/long/path/to/some/interp: bad interpreter: | ||||
| #            No such file or directory | ||||
| # | ||||
| # On macOS, the system simply assumes the interpreter is the shell and | ||||
| # tries to run with it, which is not likely 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/sh /path/to/sbang` on line 1, and move the original | ||||
| # shebang to line 2 of the script: | ||||
| # | ||||
| #     1    #!/bin/sh /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 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. | ||||
| # | ||||
| # 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). So, instrument such scripts | ||||
| # like this, using --, //, or <?php ... ?> instead of # on the second | ||||
| # line, e.g.: | ||||
| # | ||||
| #     1    #!/bin/sh /path/to/sbang | ||||
| #     2    --!/long/path/to/lua with arguments | ||||
| #     3    print "success!" | ||||
| # | ||||
| #     1    #!/bin/sh /path/to/sbang | ||||
| #     2    //!/long/path/to/node with arguments | ||||
| #     3    print "success!" | ||||
| # | ||||
| #     1    #!/bin/sh /path/to/sbang | ||||
| #     2    <?php #/long/path/to/php with arguments ?> | ||||
| #     3    <?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. | ||||
| # | ||||
|  | ||||
| # We disable two shellcheck errors below: | ||||
| # SC2124: when saving arguments, we intentionally assign as an array | ||||
| # SC2086: when splitting $shebang_line and exec args, we want to expand args | ||||
|  | ||||
| # Generic error handling | ||||
| die() { | ||||
| @@ -130,27 +61,16 @@ while read -r line && [ $lines -ne 2 ]; do | ||||
|     lines=$((lines+1)) | ||||
| done < "$script" | ||||
|  | ||||
| # shellcheck disable=SC2124 | ||||
| # this saves arguments for later and intentionally assigns as an array | ||||
| args="$@" | ||||
|  | ||||
| # handle scripts with sbang parameters, e.g.: | ||||
| # | ||||
| #   #!/<spack-long-path>/perl -w | ||||
| # | ||||
| # put the shebang line with all the parameters in the $@ array and get | ||||
| # the first element. | ||||
| # shellcheck disable=SC2086 | ||||
| set $shebang_line | ||||
| set -- "$@" | ||||
| interpreter="$1" | ||||
| arg1="$2" | ||||
|  | ||||
| # error if we did not find any interpreter | ||||
| if [ -z "$interpreter" ]; then | ||||
| if [ -z "$shebang_line"  ]; then | ||||
|     die "error: sbang found no interpreter in $script" | ||||
| fi | ||||
|  | ||||
| # parse out the interpreter and first argument | ||||
| IFS=' ' read -r interpreter arg1 rest <<EOF | ||||
| $shebang_line | ||||
| EOF | ||||
|  | ||||
| # Determine if the interpreter is a particular program, accounting for the | ||||
| # '#!/usr/bin/env PROGRAM' convention. So: | ||||
| # | ||||
| @@ -176,8 +96,8 @@ fi | ||||
| # | ||||
| if interpreter_is perl || interpreter_is ruby; then | ||||
|     # shellcheck disable=SC2086 | ||||
|     $exec $shebang_line -x "$args" | ||||
|     $exec $shebang_line -x "$@" | ||||
| else | ||||
|     # shellcheck disable=SC2086 | ||||
|     $exec $shebang_line "$args" | ||||
|     $exec $shebang_line "$@" | ||||
| fi | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Todd Gamblin
					Todd Gamblin