IPC :: Open3的问题

时间:2016-10-09 20:52:23

标签: perl ipc

我正在使用IPC :: Open3编写一个简单的脚本。该脚本不会向stdout或stderr输出任何内容,而我希望输出到两者。

完整的源代码:

#!/usr/bin/env perl 

use strict;
use warnings;
use utf8;

use IPC::Open3;

pipe my $input, my $output or die $!;
my $pid =  open3(\*STDIN, $output, \*STDERR, 'dd', 'if=/usr/include/unistd.h') or die $!;

while(<$input>) {
    print $_."\n";
}
waitpid $pid, 0;

我相当肯定我正在使用IPC :: Open3。但是,我仍然对我应该做什么感到困惑。

2 个答案:

答案 0 :(得分:2)

这是pipe。不知道为什么它在那里我不能说更多。这很好。

my $reader;
my $pid =  open3(\*STDIN, $reader, \*STDERR, 'dd', 'if=/usr/include/unistd.h') or die $!;

while(<$reader>) {
    print $_."\n";
}
waitpid $pid, 0;

我意识到它可能只是一个例子,但是如果它不是......这对你正在做的事情来说是完全矫枉过正的。你可以用反引号来实现这一点。

print `dd if=/usr/include/unistd.h`

IPC :: Open3有点过于复杂。有更好的模块,例如IPC::RunIPC::Run3

use strict;
use warnings;

use IPC::Run3;

run3(['perl', '-e', 'warn "Warning!"; print "Normal\n";'],
     \*STDIN, \*STDOUT, \*STDERR
);

答案 1 :(得分:1)

您的程序遇到以下问题:

  • \*STDIN(打开STDIN作为与孩子STDIN绑定的管道)应为<&STDIN(使用父母STDIN作为孩子的STDIN)。
  • \*STDERR(打开STDERR作为与孩子STDERR绑定的管道)应为>&STDERR(使用父母STDERR作为孩子的STDERR)。
  • 您在$output中的值被忽略并被覆盖。幸运的是,它被正确的值覆盖了!
  • 您使用的是print $_."\n";,但$_已经换行了。首先chomp,或者不添加换行符。
  • open3不是系统调用,因此它不会设置$!
  • open3出错时不会返回false;它抛出异常。

所以我们得到类似的东西:

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw( say );

use IPC::Open3;

my $pid = open3('<&STDIN', my $output, '>&STDERR',
    'dd', 'if=/usr/include/unistd.h');

while (<$output>) {
    chomp;
    say "<$_>";
}

waitpid($pid, 0);