0

使用 PHP proc_open(),我可以启动一个进程,在进程运行时一次读取STDOUTSTDERR(单独)任意数量的字节fread(),检测进程何时完成使用feof()STDOUT管道STDERR,然后用于proc_close()获取退出代码的过程。我已经在 PHP 中完成了所有这些工作。它运作良好,并给了我很多控制权。

有没有办法在 Perl 中完成所有这些事情?总而言之,我需要能够做到以下几点:

  • 启动外部进程
  • 单独阅读STDOUT_STDERR
  • 在进程运行时一次读取STDOUTSTDERR任意数量的字节(即无需等待进程完成)
  • 检测进程何时完成
  • 获取进程的退出码

提前感谢您的回答。

4

3 回答 3

3

您可以使用 Perl 的系统调用接口推出自己的解决方案,但使用内置模块 IPC::Open3 更容易。至于你的名单:

启动外部进程:

use IPC::Open3;
use IO::Handle;
use strict;

my $stdout = IO::Handle->new;
my $stderr = IO::Handle->new;
my $pid = open3(undef, $stdout, $stderr, 'my-command', 'arg1', 'arg2');

分别读取 STDOUT 和 STDERR,一次任意数量的字节:

my $line = <$stdout>;
# Or
sysread $stderr, my $buffer, 1024;

检测进程何时完成:

use POSIX qw(sys_wait_h);

waitpid $pid, 0;  # Waits for process to terminate
waitpid $pid, WNOHANG;  # Checks if the process has terminated

获取进程的退出码:

my $status = $?;  # After waitpid indicates the process has exited

请务必阅读 IPC::Open3 文档;正如它警告的那样,如果你不小心,当你有单独的 stdout 和 stderr 管道时,很容易陷入僵局。如果子进程填满了其中一个管道,它将阻塞,如果父进程读取另一个管道,它将阻塞。

于 2010-10-03T05:07:00.787 回答
2

你想要这个模块:IPC::Open3

于 2010-10-03T04:43:51.527 回答
1

你想要 IPC::Run,它会捕获 IO 并返回退出值

于 2010-10-03T10:28:37.943 回答