我有一种情况需要检测特定的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
我认为我很接近,但无法弄清楚为什么我会收到这些错误消息。
谢谢!
答案 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