IPC::Open3 的更多麻烦 [重复]
Posted
技术标签:
【中文标题】IPC::Open3 的更多麻烦 [重复]【英文标题】:More trouble with IPC::Open3 [duplicate] 【发布时间】:2016-10-09 21:19:23 【问题描述】:我在this question 中询问了 IPC::Open3。但是,我仍然遇到问题。
此代码挂起,而不是等到在标准输入上看到 EOF。它也无法向 stderr 写入任何内容。
这不是重复的,因为该问题询问的是捕获输出,而该问题询问的是输入。
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use v5.10;
use IPC::Open3;
use Symbol 'gensym';
my $output;
# pipe my $input, $output or die $!;
my $pid = open3(\*STDIN, $output, \*STDERR, 'sh',
'-c', 'echo 1 >&2; cat /usr/include/unistd.h -') or die $!;
while (<$output>)
say $output;
waitpid $pid, 0;
【问题讨论】:
这听起来像是X Y problem。你能解释一下你最终想要做什么吗?似乎您想要做的一部分是执行一个 shell 命令并捕获它的 STDERR 和 STDOUT 并显示 STDOUT 以供用户查看。您是否也想从脚本中获取 STDIN 以将其发送到 shell 命令中? 如果您只想从 shell 命令中捕获 STDERR 和 STDOUT,您可以查看 Capture::Tiny 中的捕获功能。它将让您捕获 STDERR、STDOUT 和退出代码。如果您还想在捕获 STDERR 和 STDOUT 的同时显示 STDOUT,那么 Capture::Tiny 中的 tee 函数之一可能对您有用。 @ikegami 我已经编辑了这个问题来解释为什么这不是重复的。 答案是一样的。两个程序都遇到完全相同的问题 【参考方案1】:您的程序存在以下问题:
\*STDIN
(打开STDIN
作为连接到孩子STDIN
的管道)应该是<&STDIN
(使用父母的STDIN
作为孩子的STDIN
)。
\*STDERR
(打开STDERR
作为连接到孩子STDERR
的管道)应该是>&STDERR
(使用父母的STDERR
作为孩子的STDERR
)。
say $output;
应该是 say $_;
或只是 say;
。
您使用say
,但您正在打印的值已经换行终止。要么先使用chomp
,要么改用print
。
open3
不是系统调用,所以它没有设置$!
。
open3
出错时不返回 false;它会引发异常。
请注意,如果您将单个标量作为命令传递,它将被传递给sh -c
。
#!/usr/bin/env perl
use strict;
use warnings;
use v5.10;
use IPC::Open3 qw( open3 );
my $pid = open3('<&STDIN', my $output, '>&STDERR',
'echo 1 >&2; cat /usr/include/unistd.h -');
while (<$output>)
chomp;
say "<$_>";
waitpid($pid, 0);
【讨论】:
以上是关于IPC::Open3 的更多麻烦 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 IPC::Open3 调用 cmd.exe 而不是请求的程序?