| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2017-06-24 22:22:55 -07:00
										 |  |  | # Please also see the NOTICE and LICENSE files for our notice and the LGPL. | 
					
						
							| 
									
										
										
										
											2016-05-11 21:22:25 -07:00
										 |  |  | # | 
					
						
							|  |  |  | # 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. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-06-23 00:03:23 -07:00
										 |  |  | # For Lua, scripts the second line can't start with #!, as # is not | 
					
						
							|  |  |  | # the comment character in lua (even though lua ignores #! on the | 
					
						
							|  |  |  | # *first* line of a script).  So, instrument a lua script like this, | 
					
						
							|  |  |  | # using -- instead of # on the second line: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #     1    #!/bin/bash /path/to/sbang | 
					
						
							|  |  |  | #     2    --!/long/path/to/lua with arguments | 
					
						
							|  |  |  | #     3 | 
					
						
							|  |  |  | #     4    print "success!" | 
					
						
							| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  | # | 
					
						
							|  |  |  | # 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#\#!}" | 
					
						
							| 
									
										
										
										
											2017-08-18 20:57:52 +02:00
										 |  |  |     elif [[ "$line" = '//!'*node* ]]; then | 
					
						
							|  |  |  |         interpreter="${line#//!}" | 
					
						
							| 
									
										
										
										
											2016-06-23 00:03:23 -07:00
										 |  |  |     elif [[ "$line" = '--!'*lua* ]]; then | 
					
						
							|  |  |  |         interpreter="${line#--!}" | 
					
						
							| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  |     fi | 
					
						
							|  |  |  |     lines=$((lines+1)) | 
					
						
							|  |  |  | done < "$script" | 
					
						
							| 
									
										
										
										
											2017-06-14 20:24:01 +02:00
										 |  |  | # this is ineeded for scripts with sbang parameter | 
					
						
							|  |  |  | # like ones in intltool | 
					
						
							|  |  |  | # #!/<spack-long-path>/perl -w | 
					
						
							|  |  |  | # this is the interpreter line with all the parameters as a vector | 
					
						
							|  |  |  | interpreter_v=(${interpreter}) | 
					
						
							|  |  |  | # this is the single interpreter path  | 
					
						
							|  |  |  | interpreter_f="${interpreter_v[0]}" | 
					
						
							| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Invoke any interpreter found, or raise an error if none was found. | 
					
						
							| 
									
										
										
										
											2017-06-14 20:24:01 +02:00
										 |  |  | if [[ -n "$interpreter_f" ]]; then | 
					
						
							|  |  |  |     if [[ "${interpreter_f##*/}" = "perl" ]]; then | 
					
						
							|  |  |  |         exec $interpreter_v -x "$@" | 
					
						
							| 
									
										
										
										
											2016-09-22 09:43:47 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2017-06-14 20:24:01 +02:00
										 |  |  |         exec $interpreter_v "$@" | 
					
						
							| 
									
										
										
										
											2016-09-22 09:43:47 +02:00
										 |  |  |     fi | 
					
						
							| 
									
										
										
										
											2016-03-05 04:18:48 -08:00
										 |  |  | else | 
					
						
							|  |  |  |     echo "error: sbang found no interpreter in $script" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  | fi |