2015-03-31 87 views
0

我想将其余的@ARGV发送到foo。我现在这样做:使用Perl''cmd'加入反引号...'

my $cmd = 'foo '.join ' ', @ARGV; 
my $out = `$cmd`; 

是否有可能这样做在同一行?例如有一个不存在的e选项:

my $out = qx/'foo'.join ' ', @ARGV/e; 

在更一般的情况下,我可能要做到这一点:

my $out = qx/'foo?.join(' ', keys %hash)/e; 

回答

2

的内置readpipe功能是什么,是在反引号/ qx()调用的后端,这样你就可以直接使用:

my $out = readpipe('foo' . join ' ', @ARGV); 
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(看你有哪一个perl -V:sh)和shell有自己的插值

所以你可以写my $out = qx/foo @ARGV/;但是它的主题是插值,首先是perl ,然后通过你调用的任何shell来运行

+0

那么,这是不是一个行大一点,但还是谢谢反正: ) – nowox 2015-03-31 08:46:08

+0

对我来说看起来像一条线:)'我的$ out = capture_this_command('foo',@ARGV);' – optional 2015-03-31 08:49:01

+0

如果你忽略额外的子程序,是的,你是对的:) – nowox 2015-03-31 08:51:46

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]}`' 

这构建了一个匿名数组引用,并立即dereferrences它。哈希不插入,但是这个数组上下文允许任意的Perl代码产生一个列表。另外,我非常确定编译器能够识别此成语,并在优化期间移除arrayref(de)dereferrence。

但是这真的很丑,从我的角度来看几乎难以理解。我宁愿建议:

my @keys = keys %hash; 
my $cmd = "foo @keys"; 
my $out = `$cmd`; 

提示:在一个专用的变量存储命令使日志执行命令,更容易的是真正可取的。

+0

很高兴知道。我应该提到,在我的真实例子中,我需要执行'qx/foo''键%hash''/'。无论如何,我学到了一些东西:) – nowox 2015-03-31 09:15:32

+0

@coin所以请相应更新您的问题。我不明白单引号的用法。你能添加预期的输入和输出样本吗? – 2015-03-31 09:17:46