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的管道)应该是&lt;&amp;STDIN(使用父母的STDIN作为孩子的STDIN)。 \*STDERR(打开STDERR作为连接到孩子STDERR的管道)应该是&gt;&amp;STDERR(使用父母的STDERR作为孩子的STDERR)。 say $output; 应该是 say $_; 或只是 say;。 您使用say,但您正在打印的值已经换行终止。要么先使用chomp,要么改用printopen3 不是系统调用,所以它没有设置$!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 在 Apache 下运行失败

如何检查使用 IPC::open3 执行的命令是不是挂起?

为啥 IPC::Open3 调用 cmd.exe 而不是请求的程序?

IPC::Open3 并确定孩子是不是正在等待输入

perl IPC:Open3 最小通过 perlcritic?

我们在 C 或 C++ 中是不是有类似于 IPC::Open3 的 perl