我想将剩余的@ARGV
发送给foo
。我目前这样做:
my $cmd = 'foo '.join ' ', @ARGV;
my $out = `$cmd`;
有可能在一行中完成吗?例如,使用不存在的e
选项:
my $out = qx/'foo'.join ' ', @ARGV/e;
在更一般的情况下,我可能想要这样做:
my $out = qx/'foo?.join(' ', keys %hash)/e;
答案 0 :(得分:2)
在运行命令之前,您无需组装命令。 qx()
运算符(由反引号别名)进行插值。
perl -e 'print `echo @ARGV`' foo bar
或在您的脚本中:
my $out = `foo @ARGV`
关于qx
的“可选”是什么,插值是正确的:请注意双插值可能会让你感到烦恼,而且很容易出现安全问题!
关于您的更新:尝试
perl -e '%h = (foo=>1,bar=>2); print `echo @{[keys %h]}`'
构造一个匿名的arrayref并立即对它进行derefferrence。散列不进行插值,但此数组上下文允许任意Perl代码生成列表。另外我很确定编译器会识别这个习惯用法并在优化过程中删除arrayref(de)dereferrence。
但从我的观点来看,这真的很难看,几乎无法辨认。我宁愿推荐:
my @keys = keys %hash;
my $cmd = "foo @keys";
my $out = `$cmd`;
提示:将命令存储在专用变量中会使日志记录更容易执行真正所需的命令。
答案 1 :(得分:2)
内置readpipe
函数位于反引号/ qx()
调用的后端,因此您可以直接使用它:
my $out = readpipe('foo' . join ' ', @ARGV);
答案 2 :(得分:1)
当然
my $out = capture_this_command( 'foo', @ARGV );
sub capture_this_command {
use Capture::Tiny qw/ capture /;
## local %ENV;
## delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
## $ENV{'PATH'} = '/bin:/usr/bin';
my @cmd = @_;
my( $stdout, $stderr, $exit ) = capture {
system { $cmd[0] } @cmd;
};;
if( $exit ){
die "got the exit( $exit ) and stderr: $stderr\n ";
} elsif( $stderr ){
warn "got stderr: $stderr\n ";
}
return $stdout;
}
<强>更新强> qx //是双引号,它是插值的,所以perlintro / perlsyn / perlquote 的所有内容都会说,但是,请记住,qx //调用你的shell(看看你有哪一个{{1} }}和shell有自己的插值
所以你可以写perl -V:sh
但它的插值,首先是perl,然后是你调用的任何shell