有条件的Perl Shebang?

时间:2016-03-03 05:03:09

标签: perl

我有一种情况需要检测特定的perl可执行文件/usr/goofy/bin/perl是否存在,如果是,请使用它来运行Perl脚本,否则使用/usr/bin/perl

我一直在努力使用这个名为perlshebang.pl的小POC脚本:

#!/bin/sh -e
perls="/usr/goofy/bin/perl /usr/bin/perl"
for pl_exec in $perls
do
    if [ -x $pl_exec ]; then
        exec "$pl_exec -w -S \"$0\" ${1+\"$@\"}"
    fi
done

print "[$^X] Whoop!\n";

当我在没有/usr/goofy/bin/perl的系统上运行时,我收到以下错误消息:

./perlshebang.pl: 6: exec: /usr/bin/perl -w -S "./perlshebang.pl" : not found

当我在一个有/usr/goofy/bin/perl的系统上运行它时,我收到一条similuar错误消息:

./perlshebang.pl: line 6: /usr/goofy/bin/perl -w -S "./perlshebang.pl" : No such file or directory

我认为我很接近,但无法弄清楚为什么我会收到这些错误消息。

谢谢!

4 个答案:

答案 0 :(得分:3)

要回答您的问题“我为什么收到这些错误消息?”,问题出在exec行:

exec "/path/to/cmd arg arg"
# This will attempt to execute a file named "cmd arg arg"
# (with spaces in name) in directory /path/to/

对比
exec /path/to/cmd arg arg
# This will attempt to execute a file named "cmd" in directory
# /path/to/, with arguments "arg" and "arg"

所以,这就是为什么shell抱怨它无法找到你的可执行文件。您没有名为perl -w -s "perlshebang.pl"的文件,既不在/usr/bin/下也不在/usr/goofy/bin/下。

答案 1 :(得分:2)

如果您发布使用此黑客的软件,这对我来说听起来有点难看

如果您别无选择,我建议您确保总是 /usr/goofy/bin/perl,然后使用shebang line

#!/usr/goofy/bin/perl

在你的所有脚本上。

对于要使用系统perl的系统,只需将/usr/goofy/bin/perl符号链接设为/usr/bin/perl

答案 2 :(得分:1)

您可以从运行/usr/bin/perl的Perl脚本中运行该想法。在你应该运行的脚本中使用shebang行和'goofy perl'。然后运行以下包装器,然后正常调用脚本(其名称和参数)。

#!/usr/bin/perl

exec "@ARGV";
exec "/usr/bin/perl @ARGV";

print STDERR "Couldn't execute either.\n";

让我们调用上面的pick_perl.pl,您的脚本为script.pl。全部运行

pick_perl.pl script.pl args-for-script

exec将正在运行的程序替换为它执行的程序,即。它加载新程序。因此,你的脚本运行自己的shebang。如果那个failes exec安静地返回(带有false)并且执行下一个语句,那么另一个Perl运行脚本(覆盖shebang)。如果脚本的shebang失败,而且第一个exec因任何原因无法执行,则会发生这种情况。

如果您希望/需要运行检查,请将exec放入完整的if块中。如果-e没有足够的保证,也可以进一步询问'goofy_perl'文件。

#!/usr/bin/perl

$system_perl = "/usr/bin/perl";
$goofy_perl  = "/usr/goofy/bin/perl";

# Your 'goofy_perl' script with its arguments
@script_cmd = @ARGV;

if (-x $goofy_perl) {  exec "@script_cmd" }

exec "$system_perl @script_cmd";

@script_cmd拥有脚本的完整命令行(具有'goofy_perl'shebang)。

答案 3 :(得分:1)

我的一位同事想出了这个。我不确定我是否完全理解它,但似乎工作正常:

#!/bin/sh
#! -*-perl-*- 
eval ' if test -x /usr/goofy/bin/perl ; then
    exec /usr/goofy/bin/perl -x -S $0 ${1+"$@"};
elif test -x /usr/bin/perl ; then 
    exec /usr/bin/perl -x -S $0 ${1+"$@"};
fi '
if $running_under_some_shell;


use strict; 
use warnings; 
print "hello world\n"; # if $foo; 
printf("running %s v(%vd)\n", $^X, $^V);

__END__

unpod like docs. 
See http://perldoc.perl.org/perlrun.html