Skip to content

Instantly share code, notes, and snippets.

@wu
Last active January 1, 2016 08:39
Show Gist options
  • Save wu/8119651 to your computer and use it in GitHub Desktop.
Save wu/8119651 to your computer and use it in GitHub Desktop.
Exercise a shebang limitation in bash on OS X and Solaris 10 that affects plenv
#!/perl
use strict;
use warnings;
use Test::More;
use File::Temp qw/ tempdir /;
# See: https://github.com/wu/journal/blob/master/2014.01.05.plenv-shebang.org
# run the test cases:
# curl -fsSkL https://gist.github.com/wu/8119651/raw | perl -
# failures on OS X:
#
# ok 1 - checking that we could find plenv perl shim
# This is a test
# ok 2 - shell script executes shim directly, passing in path to perl script
# /tmp/tmpdir-9yUYsXzlvp/test.pl: line 2: print: command not found
# not ok 3 - shell script executes script using shebang
# # Failed test 'shell script executes script using shebang'
# # at broken.t line 78.
# This is a test
# ok 4 - shell script executes script using shebang, with work-around
# This is a test
# ok 5 - shell script executes script using shebang with zsh
# /tmp/tmpdir-9yUYsXzlvp/test.bash-bug.pl: line 3: print: command not found
# not ok 6 - minimal bash shim that execs perl, called via shebang (no plenv)
# # Failed test 'minimal bash shim that execs perl, called via shebang (no plenv)'
# # at broken.t line 91.
# This is a test
# ok 7 - nested shebang with bash (no plenv)
# 1..7
# # Looks like you failed 2 tests of 7.
my $tempdir = tempdir( "/tmp/tmpdir-XXXXXXXXXX", CLEANUP => 1 );
my $perl_shim;
for my $check_path ( "/opt/boxen/plenv/shims/perl",
"$ENV{HOME}/.plenv/shims/perl",
) {
if ( -x $check_path ) {
$perl_shim = $check_path;
}
}
ok( -x $perl_shim,
"checking that we could find plenv perl shim"
);
{
my ( $fh, $path );
LINE:
while ( my $line = <DATA> ) {
chomp $line;
if ( $line =~ m|^FILE\: (.*)$| ) {
$path = "$tempdir/$1";
open($fh, ">", $path) or die "Couldn't open $path for writing: $!\n";
}
elsif ( $line =~ m|^\_+$| ) {
close $fh or die "Error closing file: $!\n";
system( "chmod", "a+x", $path ) == 0 or die "Couldn't chmod $path\n";
}
elsif ( $line ) {
$line =~ s|\$\{tempdir\}|$tempdir|g;
$line =~ s|\$\{perl_shim\}|$perl_shim|g;
print $fh $line, "\n";
}
}
}
if ( -x $perl_shim ) {
ok( system( "$tempdir/test.shim.sh" ) == 0,
"shell script executes shim directly, passing in path to perl script"
);
ok( system( "$tempdir/test.shebang.sh" ) == 0,
"shell script executes script using shebang"
);
ok( system( "$tempdir/test.shebang.perlrun.sh" ) == 0,
"shell script executes script using shebang, with work-around"
);
ok( system( "$tempdir/test.shebang.zsh" ) == 0,
"shell script executes script using shebang with zsh"
);
}
if ( -x "/usr/bin/perl" ) {
ok( system( "$tempdir/test.bash-bug.pl" ) == 0,
"minimal bash shim that execs perl, called via shebang (no plenv)"
);
}
ok( system( "$tempdir/test.bash-shebang-nested.sh" ) == 0,
"nested shebang with bash (no plenv)"
);
done_testing;
__DATA__
FILE: test.pl
#!${perl_shim}
print "This is a test\n";
_____________________________________________________________________________
FILE: test.shim.sh
#!/usr/bin/env bash
# execute the shim, passing in the path to the script
${perl_shim} ${tempdir}/test.pl
_____________________________________________________________________________
FILE: test.shebang.sh
#!/usr/bin/env bash
# execute the script using the shebang
${tempdir}/test.pl
_____________________________________________________________________________
FILE: test.shebang.zsh
#!/usr/bin/env zsh
# execute the script using the shebang
${tempdir}/test.pl
_____________________________________________________________________________
FILE: test.perlrun.pl
#!${perl_shim}
# include code from perlrun for broken shebang
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;
print "This is a test\n";
_____________________________________________________________________________
FILE: test.shebang.perlrun.sh
#!/usr/bin/env bash
# execute the script using the shebang
${tempdir}/test.perlrun.pl
_____________________________________________________________________________
FILE: test.basic-shim.sh
#!/usr/bin/env bash
# the simplest possible perl shim
exec /usr/bin/perl "$@"
_____________________________________________________________________________
FILE: test.bash-bug.pl
#!${tempdir}/test.basic-shim.sh
# use the basic shim in the shebang
print "This is a test\n";
_____________________________________________________________________________
FILE: test.bash-shim.sh
#!/usr/bin/env bash
# the simplest possible bash shim
exec bash "$@"
_____________________________________________________________________________
FILE: test.bash-shebang-nested.sh
#!${tempdir}/test.bash-shim.sh
# use the basic shim in the shebang
echo "This is a test";
_____________________________________________________________________________
@wu
Copy link
Author

wu commented Jan 10, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment