我正在尝试制作一个主perl脚本,调用子perl脚本并通过管道进行交互.
我为master写了这段代码:
#!/usr/bin/env perl
use strict;
use warnings;
use IPC::Open3;
my @children;
for my $i ( 0 .. 4 ) {
print "Master: " . $i . ", I summon you\n";
$children[$i] = {};
$children[$i]->{'pid'} = open3( my $CH_IN, my $CH_OUT, my $CH_ERR, 'perl child.pl -i ' . $i );
$children[$i]->{'_STDIN'} = $CH_IN;
$children[$i]->{'_STDOUT'} = $CH_OUT;
$children[$i]->{'_STDERR'} = $CH_ERR;
my $line = readline $children[$i]->{'_STDOUT'};
print $line ;
}
print "Master: Go fetch me the sacred crown\n";
for my $i ( …Run Code Online (Sandbox Code Playgroud) 我想在子进程中压缩输出并只读取stderr.perlfaq8建议做以下事项:
# To capture a program's STDERR, but discard its STDOUT:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);
Run Code Online (Sandbox Code Playgroud)
但后来perlcritic争论使用裸字文件句柄.
我唯一可以设计的是将select新打开的描述符/dev/null改为on STDOUT,如下所示:
# To capture a program's STDERR, but discard its STDOUT:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open my $null, ">", File::Spec->devnull;
my $old_stdout = select( $null );
my $pid = …Run Code Online (Sandbox Code Playgroud) 在我们的一个模块中,我们检查给定的二进制(varnishd)是否存在,如果存在,我们运行其他测试.
为了执行检查,我们正在使用IPC::Open3,如下所示(示例为了清晰起见而被剥离):
perl -MIPC::Open3 -le '
my $binary = "varnishd";
my $pid = IPC::Open3::open3(my($in, $out), undef, $binary, "-V");
waitpid $pid, 0; print $?'
Run Code Online (Sandbox Code Playgroud)
在Debian Squeeze或Ubuntu Natty下,使用perl 5.10.1,如果varnishd在系统上找不到,则会打印出来65280.如果更改$binary为perl,则(正确)打印0.
但是,使用Ubuntu Precise和perl 5.14.2,这不再以相同的方式工作,并产生以下结果:
$ perl -MIPC::Open3 -le '
my $binary = "varnishd";
my $pid = IPC::Open3::open3(my($in, $out), undef, $binary, "-V");
waitpid $pid, 0; print $?'
open3: exec of varnishd -V failed at -e line1
Run Code Online (Sandbox Code Playgroud)
$binary …
我正在阅读perlcritic文档以避免反引号并在此处使用IPC :: Open3:
http://perl-critic.stacka.to/pod/Perl/Critic/Policy/InputOutput/ProhibitBacktickOperators.html
我试图找到最简单的选项,它将起作用并满足perlcritic:
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3 'open3'; $SIG{CHLD} = 'IGNORE';
my $cmd = 'ls';
my ($w,$r,$e); open3($w,$r,$e,$cmd);
my @o = <$r>; my @e = <$e>;
1;
Run Code Online (Sandbox Code Playgroud)
但它抱怨以下错误:
Use of uninitialized value in <HANDLE> at ipc_open3.pl line 7
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
编辑:好的,这就是我所拥有的.除非有办法简化它,否则我会坚持这样:
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3 'open3'; $SIG{CHLD} = 'IGNORE';
use Symbol 'gensym';
my $cmd = 'ls';
my ($w,$r,$e) = (undef,undef,gensym); my $p = open3($w,$r,$e,$cmd);
my @o = <$r>; my @e = <$e>;
1;
Run Code Online (Sandbox Code Playgroud)