| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  | #!/bin/bash | 
					
						
							| 
									
										
										
										
											2016-05-11 21:22:25 -07:00
										 |  |  | ############################################################################## | 
					
						
							|  |  |  | # Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. | 
					
						
							|  |  |  | # Produced at the Lawrence Livermore National Laboratory. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This file is part of Spack. | 
					
						
							|  |  |  | # Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. | 
					
						
							|  |  |  | # LLNL-CODE-647188 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # For details, see https://github.com/llnl/spack | 
					
						
							|  |  |  | # Please also see the LICENSE file for our notice and the LGPL. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  | # it under the terms of the GNU Lesser General Public License (as | 
					
						
							|  |  |  | # published by the Free Software Foundation) version 2.1, February 1999. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, but | 
					
						
							|  |  |  | # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and | 
					
						
							|  |  |  | # conditions of the GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  | # License along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 
					
						
							|  |  |  | ############################################################################## | 
					
						
							| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  | # | 
					
						
							|  |  |  | # `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 |