【问题标题】:More trouble with IPC::Open3 [duplicate]IPC::Open3 的更多麻烦 [重复]
【发布时间】: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 我已经编辑了这个问题来解释为什么这不是重复的。
  • 答案是一样的。两个程序都遇到完全相同的问题

标签: perl ipc


【解决方案1】:

您的程序存在以下问题:

  • \*STDIN(打开STDIN作为连接到孩子STDIN的管道)应该是&lt;&amp;STDIN(使用父母的STDIN作为孩子的STDIN)。
  • \*STDERR(打开STDERR作为连接到孩子STDERR的管道)应该是&gt;&amp;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);

【讨论】:

    猜你喜欢
    • 2013-06-15
    • 2023-03-09
    • 2017-01-11
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2017-02-18
    • 2012-09-13
    • 1970-01-01
    相关资源
    最近更新 更多