根据manual,IPC::Open3::open3
的语法是
$pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, 'some cmd and args', 'optarg', ...);
我对前三个参数感到困惑。这些是对typeglobs的引用吗?
我尝试了以下内容:
my $pid=open3("STDIN", "STDOUT", "STDERR", $cmd);
my $pid=open3(*STDIN, *STDOUT, *STDERR, $cmd);
my $pid=open3(\*STDIN, \*STDOUT, \*STDERR, $cmd);
my $pid=open3('<&STDIN', '>&STDOUT', '>&STDERR', $cmd);
但只有4号,似乎有效。根据手册,我认为3号也应该有效。例如:
use warnings;
use strict;
use feature qw(say);
use IPC::Open3;
my $cmd="sleep 1; echo This STDOUT; sleep 1; echo 'This is STDERR' 1>&2; sleep 1; echo -n 'Reading STDIN: '; read a";
my $pid=open3('<&STDIN', '>&STDOUT', '>&STDERR', $cmd);
say "Waiting for child..";
wait;
say "Done.";
答案 0 :(得分:3)
如果传递字符串'<&STDIN'
和'>&STDOUT'
,那么子进程将获得Perl程序自己的标准输入和输出句柄的副本,并且可以在没有任何进一步干预的情况下读取和写入它们
使用typeglob引用指定文件句柄是非常不同的事情。文档中的CHLD_OUT
文件句柄是子进程的STDOUT
,它允许您的Perl程序从CHLD_OUT
读取这样您就可以获取并处理它发送的数据。在此处使用STDOUT
将无效,因为它是Perl进程的输出文件句柄。如果你真的想要的话,你可以使用STDIN
,但这样你就无法阅读最初提供给标准输入的任何内容。
等效点适用于CHLD_IN
,print
是您STDOUT
向子进程发送数据的句柄。同样,你可以在这里使用CHLD_ERR
,但这会剥夺你原来的标准输出通道。在任何情况下,您仍然需要为STDERR
创建另一个文件句柄,因为您将从中读取以查看孩子发送到其标准错误输出的内容,当然您无法从open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, 'command')
读取。
所以你能做的最好就是替换
open3(\*STDOUT, \*STDIN, \*CHLD_ERR, 'command')
与
{{1}}
但文件句柄并不昂贵,那么为什么要让自己失去标准的输入和输出呢?更好的是创建三个新文件句柄并与所有六个一起使用。