104 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/sh
 | 
						|
#
 | 
						|
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
 | 
						|
# sbang project developers. See the top-level COPYRIGHT file for details.
 | 
						|
#
 | 
						|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
 | 
						|
 | 
						|
#
 | 
						|
# `sbang`: Run scripts with 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 arguments
 | 
						|
#
 | 
						|
# `sbang` will run the real interpreter with the script as its argument.
 | 
						|
#
 | 
						|
# See https://github.com/spack/sbang for more details.
 | 
						|
#
 | 
						|
 | 
						|
# Generic error handling
 | 
						|
die() {
 | 
						|
    echo "$@" 1>&2;
 | 
						|
    exit 1
 | 
						|
}
 | 
						|
 | 
						|
# set SBANG_DEBUG to make the script print what would normally be executed.
 | 
						|
exec="exec"
 | 
						|
if [ -n "${SBANG_DEBUG}" ]; then
 | 
						|
    exec="echo "
 | 
						|
fi
 | 
						|
 | 
						|
# First argument is the script we want to actually run.
 | 
						|
script="$1"
 | 
						|
 | 
						|
# ensure that the script actually exists
 | 
						|
if [ -z "$script" ]; then
 | 
						|
    die "error: sbang requires exactly one argument"
 | 
						|
elif [ ! -f "$script" ]; then
 | 
						|
    die "$script: no such file or directory"
 | 
						|
fi
 | 
						|
 | 
						|
# Search the first two lines of script for interpreters.
 | 
						|
lines=0
 | 
						|
while read -r line && [ $lines -ne 2 ]; do
 | 
						|
    if [ "${line#\#!}" != "$line" ]; then
 | 
						|
        shebang_line="${line#\#!}"
 | 
						|
    elif [ "${line#//!}" != "$line" ]; then      # // comments
 | 
						|
        shebang_line="${line#//!}"
 | 
						|
    elif [ "${line#--!}" != "$line" ]; then      # -- lua comments
 | 
						|
        shebang_line="${line#--!}"
 | 
						|
    elif [ "${line#<?php\ }" != "$line" ]; then  # php comments
 | 
						|
        shebang_line="${line#<?php\ \#!}"
 | 
						|
        shebang_line="${shebang_line%\ ?>}"
 | 
						|
    fi
 | 
						|
    lines=$((lines+1))
 | 
						|
done < "$script"
 | 
						|
 | 
						|
# error if we did not find any interpreter
 | 
						|
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:
 | 
						|
#
 | 
						|
#     interpreter_is perl
 | 
						|
#
 | 
						|
# will be true for '#!/usr/bin/perl' and '#!/usr/bin/env perl'
 | 
						|
interpreter_is() {
 | 
						|
    if [ "${interpreter##*/}" = "$1" ]; then
 | 
						|
        return 0
 | 
						|
    elif [ "$interpreter" = "/usr/bin/env" ] && [ "$arg1" = "$1" ]; then
 | 
						|
        return 0
 | 
						|
    else
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
if interpreter_is "sbang"; then
 | 
						|
    die "error: refusing to re-execute sbang to avoid infinite loop."
 | 
						|
fi
 | 
						|
 | 
						|
# Finally invoke the real shebang line
 | 
						|
# ruby and perl need -x to ignore the first line of input (the sbang line)
 | 
						|
#
 | 
						|
if interpreter_is perl || interpreter_is ruby; then
 | 
						|
    # shellcheck disable=SC2086
 | 
						|
    $exec $shebang_line -x "$@"
 | 
						|
else
 | 
						|
    # shellcheck disable=SC2086
 | 
						|
    $exec $shebang_line "$@"
 | 
						|
fi
 |