perl - 如何使用 Perl IPC::Run3 从子进程读取标准输出和标准错误?

我想运行一个 make从 Perl 脚本中获取命令,这样我就可以捕获它的 stdout 和 stderr 流。我知道我可以使用 open(MAKE, "make 2>&1 |")但这会给构建正确的 shell 命令以将参数传递给 make 带来问题,并使用 open(MAKE, "-|", @makecmd, "2>&1")不起作用,因为将命令作为数组传递不会生成子 shell 来进行重定向。

我遇到了 IPC::Run3我已经让它工作了,但是我对文件句柄的使用很丑陋——基本上我不得不生成一个 cat子进程以获得我可以告诉的句柄 IPC::Run3写入以便我的脚本可以从中读取,以及我尝试通过 STDIN为此目的失败了。我做错了什么?

#!/usr/bin/perl

use strict;
use warnings;
use IPC::Run3;

#my $pipe = \*STDIN;           #-- this produces no output and hangs
#open(my $pipe, "<&STDIN");    #-- this outputs "foo bar" and hangs
open(my $pipe, "|cat");        #-- this works, but extra process is ugly

run3 "echo foo; echo bar >&2", \undef, $pipe, $pipe;

while (<$pipe>) {
    print ">>> $_";
}

最佳答案

你不知道。您改用 IPC::Run。天真地使用 IPC::Open3 会让你陷入僵局。避免这种情况涉及使用 IO::Select 或其他一些机制。涉及的工作范围很广。 IPC::Open3 对于实际使用来说太低级了。


也就是说,您只处理一个文件句柄。 可以使用 open3 相对简单地完成。

use IPC::Open3 qw( open3 );

open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
*CHILD_STDIN if 0;
pipe(local (*READER, *WRITER)) or die $!;
my $pid = open3('<&CHILD_STDIN', '>&WRITER', '>&WRITER', @cmd);

close(WRITER);

while (<READER>) {
   ...
}

waitpid($pid);

呸!使用 IPC::Run 会更干净。

use IPC::Run qw( run );

run \@cmd, \undef, '>pipe', \my $pipe, '2>&1';

while (<$pipe>) {
   ...
}

close($pipe);

好吧,文档就是这么说的,但它不起作用。你其实需要

use IPC::Run qw( run );
use Symbol   qw( gensym );

run \@cmd, \undef, '>pipe', (my $pipe = gensym), '2>&1';

while (<$pipe>) {
   ...
}

close($pipe);

如果你想要所有的输出,你可以简单地使用

use IPC::Run qw( run );

run \@cmd, \undef, \my $output;

最后,您提到了构建 shell 命令的问题。

你要找的是

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote(@cmd) . ' 2>&1';
open(my $pipe, '-|', $cmd);

while (<$pipe>) {
   ...
}

close($pipe);

https://stackoverflow.com/questions/67901677/

相关文章:

android - 臭名昭著的高度 :100% issue on chrome for androi

python - 是否有一个 Binance API 端点来关闭所有头寸?

java - 如何在 Java 数组上设置新的属性或方法?

javascript - onClick 从类更改为函数

javascript - 如何从标称字符串中删除 0,但不从 javascript 中的小数中删除

bash - 在组合前面的数据的同时在多行中添加值

r - 将数据帧的每一行乘以它的向量 R

r - ggplot : create a facet grid with free scales

c++ - 如何删除结构 vector 的重复项 C++

python - 如何找到 pandas 数据框字符串列中的最大单词数?