perl - 如何使用 Perl IPC::Run3 从子进程中读取标准输出和标准错误?
问题描述
我想make
从 Perl 脚本运行命令,以便捕获它的 stdout 和 stderr 流。我知道我可以使用open(MAKE, "make 2>&1 |")
,但这会给构建正确的 shell 命令以将参数传递给make
,并且 usingopen(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);
推荐阅读
- ruby-on-rails - 。零?函数在 Ruby on Rails 5 中不起作用
- c# - ASP.NET MVC - 如何安全地保存用户密码以进行 SQL Server 身份验证?
- reactjs - 如何在 ReactJS 中使用路由
- fftw - 如何在 Windows 10 上使用 dlltool 生成 .lib 文件?
- javascript - 在多个段落中查找常用词 Javascript
- git - 推送到朋友回购
- rust - 如何将结构化数据保存到文件?
- javascript - Material-UI的`AppBar中的主题没有改变?
- docker - 无法在 Heroku 上安装 wkhtmltopdf:命令 '/bin/sh -c curl 返回非零代码:6
- python - 在编写不和谐机器人时如何以及是否可以拆分字符串?