一种基本方法是使用管道打开,您可以在其中open https://perldoc.perl.org/functions/open.html通往分叉进程的管道。然后STDOUT
从子级通过管道传输到父级中的文件句柄,或者父级通过管道传输到其STDIN
.
use warnings;
use strict;
my @cmd = qw(ls -l .); # your command
my $pid = open(my $fh, '-|', @cmd) // die "Can't open pipe from @cmd: $!";
while (<$fh>) {
print;
}
close $fh or die "Error closing pipe from @cmd: $!";
This way the parent receives child's STDOUT
right as it is emitted.†
您可以对错误检查做更多的事情,请参阅手册页,close https://perldoc.perl.org/functions/close.html, and $?在佩尔瓦尔 https://perldoc.perl.org/perlvar.html#%24%3f。另外,安装一个处理程序SIGPIPE
, see perlipc https://perldoc.perl.org/perlipc.html and %SIG在佩尔瓦尔 https://perldoc.perl.org/perlvar.html#%SIG.
有些模块可以使运行和管理外部命令变得更加容易,特别是检查错误。然而,捕获::微小 https://metacpan.org/pod/Capture::Tiny and IPC::运行3 https://metacpan.org/pod/IPC::Run3使用文件传输外部程序的流。
另一方面,IPC::Run https://metacpan.org/pod/IPC::Run为您提供更多的控制力和力量。
执行代码"...每次从孩子那里读取一些数据时" https://metacpan.org/pod/IPC::Run#Redirection-Operators使用回调
use warnings;
use strict;
use IPC::Run qw(run);
my @cmd = (
'perl',
'-le',
'STDOUT->autoflush(1); for (qw( abc def ghi )) { print; sleep 1; }'
);
run \@cmd, '>', sub { print $_[0] };
一旦你使用IPC::Run
还有更多可能,包括更好的错误询问、为进程设置伪 tty 等。例如,使用>pty>
代替>
设置类似终端的环境,以便运行的外部程序可以返回行缓冲并提供更及时的输出。如果对如何管理流程的需求变得更加复杂,那么使用该模块的工作将会更容易。
谢谢ikegami https://stackoverflow.com/users/589924/ikegami征求意见,包括演示@cmd
.
† To demonstrate that the parent receives child's STDOUT
as it is emitted use a command that emits output with delays. For example, instead of ls -l
above use
my @cmd = (
'perl',
'-le',
'STDOUT->autoflush(1); for (qw( abc def ghi )) { print; sleep 1; }'
);
这个 Perl 一行行每隔一秒打印单词,这就是它们在屏幕上的显示方式。