从open3读取HANDLE_IN和HANDLE_ERR

时间:2013-05-06 14:39:25

标签: perl

我使用open 3来执行我的python脚本我想看看handle_out和handle_error的输出我怎么能看到它。我正在做类似下面的事情?它打印

sel : IO::Select=ARRAY(0x18e15040)


local (*HANDLE_IN, *HANDLE_OUT,*HANDLE_ERR);
       open3( \*HANDLE_IN, \*HANDLE_OUT, \*HANDLE_ERR, "@args")  or die "open3 failed $!\n";

 my $sel = new IO::Select;
        $sel->add(\*HANDLE_OUT,\*HANDLE_ERR);
        print "sel : $sel";

谢谢

2 个答案:

答案 0 :(得分:2)

open3仍然是一个相当低级别的解决方案。它为您处理许多事情,但它对处理进程间通信(ipc)没有帮助。

如果您想独立阅读孩子的STDOUT和STDERR,或者您同时从孩子那里发送和接收数据,那么您就会遇到死锁。

尽管可以使用select来避免死锁,但它非常复杂。我不建议你走那条路。我建议您使用IPC::Run3(最简单)或IPC::Run(更多功能)而不是open3,绕过整个问题。

答案 1 :(得分:0)

您不需要使用IO :: Select。这些只是普通的文件句柄。

while (my $line = <HANDLE_OUT>) {
    print $line;
}

最好使用现代风格,如IPC::Open3的文档中所示。

my ($wtr, $rdr, $err);
use Symbol 'gensym'; $err = gensym;
$pid = open3($wtr, $rdr, $err,
    'some cmd and args', 'optarg', ...);

以下内容表明上述建议是错误的,因为它会导致死锁。由于上述建议,以下程序永远不会退出:

perl -MIPC::Open3=open3 -E'
    my $pid = open3(
       local *TO_CHILD,
       local *FROM_CHILD,
       local *FROM_CHILD_ERROR,
       "perl",
       "-E" => q{say STDERR "x"x(64*1024); say "y";},
    );
    say "Getting STDOUT";
    print while <FROM_CHILD>;
    say "Getting STDERR";
    print while <FROM_CHILD_ERR>;
    waitpid($pid, 0);
'