1#!/bin/sh 2# Test env -S in a #! line of a script. 3 4# Copyright (C) 2018-2023 Free Software Foundation, Inc. 5 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19 20. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 21print_ver_ env 22print_ver_ printf 23 24require_perl_ 25 26# a shortcut to avoid long lines 27dir="$abs_top_builddir/src" 28 29cat <<EOF > shebang || framework_failure_ 30#!$SHELL 31EOF 32cat <<\EOF >> shebang || framework_failure_ 33# Execute a script as per 3 argument shebang 34# but without length limits (127 on Linux for example). 35script="$1"; shift 36shebang=$(sed -n 's/^#!//p;q' < "$script") 37interp=$(printf '%s' "$shebang" | cut -d' ' -f1) 38rest=$(printf '%s' "$shebang" | cut -s -d' ' -f2-) 39test "$rest" && exec "$interp" "$rest" "$script" "$@" 40exec "$interp" "$script" "$@" 41EOF 42chmod a+x shebang || framework_failure_ 43 44# A simple shebang program to call our new "env" 45printf "#!$dir/env sh\necho hello\n" > env_test || framework_failure_ 46chmod a+x env_test || framework_failure_ 47 48# Verify we can run the shebang which is not the case if 49# there are spaces in $abs_top_builddir. 50./shebang ./env_test || skip_ "Error running env_test script" 51 52# env should execute 'printf' with 7 parameters: 53# 'x%sx\n', 'A', 'B' from the "-S" argument, 54# the name of the executed script, and its 3 parameters (C,D,'E F'). 55# Ignoring the absolute paths, the script is: 56# #!env -S printf x%sx\n A B 57printf "#!$dir/env -S $dir/printf "'x%%sx\\n A B\n' > env1 || framework_failure_ 58chmod a+x env1 || framework_failure_ 59cat<<\EOF>exp1 || framework_failure_ 60xAx 61xBx 62x./env1x 63xCx 64xDx 65xE Fx 66EOF 67./shebang ./env1 C D "E F" > out1 || fail=1 68compare exp1 out1 || fail=1 69 70 71# similar to the above test but with quotes, the first parameter should be 72# 'A B' and not two parameters 'A','B'. 73# Ignoring the absolute paths, the script is: 74# #!env -S printf x%sx\n "A B" 75printf "#!$dir/env -S $dir/printf "'x%%sx\\n "A B"\n' > env2 || 76 framework_failure_ 77chmod a+x env2 || framework_failure_ 78cat<<\EOF>exp2 || framework_failure_ 79xA Bx 80x./env2x 81EOF 82./shebang ./env2 > out2 || fail=1 83compare exp2 out2 || fail=1 84 85 86# backslash-underscore instead of spaces. 87# Ignoring the absolute paths, the script is: 88# #!env -Sprintf\_x%sx\n\_Y 89printf "#!$dir/env -S$dir/printf"'\\_x%%sx\\n\\_Y\n' > env3 || 90 framework_failure_ 91chmod a+x env3 || framework_failure_ 92cat<<\EOF>exp3 || framework_failure_ 93xYx 94x./env3x 95xWx 96EOF 97./shebang ./env3 W > out3 || fail=1 98compare exp3 out3 || fail=1 99 100 101 102# Test comments - The "#C D" should be ignored. 103# Ignoring the absolute paths, the script is: 104# #!env -Sprintf x%sx\n A#B #C D 105printf "#!$dir/env -S$dir/printf"' x%%sx\\n A#B #C D\n' > env4 \ 106 || framework_failure_ 107chmod a+x env4 || framework_failure_ 108cat<<\EOF>exp4 || framework_failure_ 109xA#Bx 110x./env4x 111xZx 112EOF 113./shebang ./env4 Z > out4 || fail=1 114compare exp4 out4 || fail=1 115 116 117# Test with a simple Perl usage. 118# (assume Perl is in $PATH, as it is required for the test suite). 119# Ignoring the absolute paths, the script is: 120# #!env -S perl -w -T 121# print "hello\n"; 122{ printf "#!$dir/env -S $PERL -w -T\n" ; 123 printf 'print "hello\\n";\n' ; } > env5 || framework_failure_ 124chmod a+x env5 || framework_failure_ 125cat<<\EOF>exp5 || framework_failure_ 126hello 127EOF 128./shebang ./env5 > out5 || fail=1 129compare exp5 out5 || fail=1 130 131 132# Test with a more complex Perl usage. 133# Ignoring the absolute paths, the script is: 134# #!env -S perl -mFile::Basename=basename -e "print basename(\$ARGV[0]);" 135# The backslash before the '$' is required to prevent env(1) from treating 136# $ARGV as an (invalid syntax) envvar, and pass it as-is to Perl. 137{ printf "#!$dir/env -S " ; 138 printf "$PERL -mFile::Basename=basename -e " ; 139 printf '"print basename(\\$ARGV[0]);"\n' ; } > env6 || framework_failure_ 140chmod a+x env6 || framework_failure_ 141# Note: the perl script does not output a newline. 142printf "env6" > exp6 || framework_failure_ 143./shebang ./env6 > out6 || fail=1 144compare exp6 out6 || fail=1 145 146 147Exit $fail 148