IPC::Open3 有问题
Trouble with IPC::Open3
我正在使用 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 不正确。然而,我仍然对我应该做什么感到困惑。
是 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::Run and IPC::Run3.
use strict;
use warnings;
use IPC::Run3;
run3(['perl', '-e', 'warn "Warning!"; print "Normal\n";'],
\*STDIN, \*STDOUT, \*STDERR
);
您的程序存在以下问题:
\*STDIN
(打开 STDIN
作为连接到 child 的 STDIN
的管道)应该是 <&STDIN
(使用 parent 的 STDIN
作为 child 的 STDIN
).
\*STDERR
(打开 STDERR
作为连接到 child 的 STDERR
的管道)应该是 >&STDERR
(使用 parent 的 STDERR
作为 child 的 STDERR
).
- 您在
$output
中设置的值将被忽略和覆盖。幸运的是,它正在被正确的值覆盖!
- 您使用
print $_."\n";
,但 $_
已经是 newline-terminated。要么先 chomp
,要么不添加换行符。
open3
不是系统调用,因此不会设置 $!
.
open3
不会在错误时 return 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);
我正在使用 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 不正确。然而,我仍然对我应该做什么感到困惑。
是 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::Run and IPC::Run3.
use strict;
use warnings;
use IPC::Run3;
run3(['perl', '-e', 'warn "Warning!"; print "Normal\n";'],
\*STDIN, \*STDOUT, \*STDERR
);
您的程序存在以下问题:
\*STDIN
(打开STDIN
作为连接到 child 的STDIN
的管道)应该是<&STDIN
(使用 parent 的STDIN
作为 child 的STDIN
).\*STDERR
(打开STDERR
作为连接到 child 的STDERR
的管道)应该是>&STDERR
(使用 parent 的STDERR
作为 child 的STDERR
).- 您在
$output
中设置的值将被忽略和覆盖。幸运的是,它正在被正确的值覆盖! - 您使用
print $_."\n";
,但$_
已经是 newline-terminated。要么先chomp
,要么不添加换行符。 open3
不是系统调用,因此不会设置$!
.open3
不会在错误时 return 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);