4

现在我有一个 perl 脚本,它在某个时刻收集然后处理几个 bash 命令的输出,现在我是这样做的:

if ($condition) {
  @output = `$bashcommand`;
  @output1 = `$bashcommand1`;
  @output2 = `$bashcommand2`;
  @output3 = `$bashcommand3`;
}

问题是,这些命令中的每一个都需要相当长的时间,因此,我想知道我是否可以同时运行它们。

4

4 回答 4

4

在 Unix 系统上,您应该能够打开多个命令管道,然后运行循环调用IO::Select以等待其中任何一个准备好读取;继续阅读和啜饮他们的输出(用sysread),直到他们都到达文件末尾。

不幸的是,显然 Unix 的 Win32 仿真select无法处理文件 I/O,因此要在 Windows 上实现它,您还必须添加一层套接字 I/O,它的select工作原理,请参阅perlmonks

于 2012-02-06T19:44:56.273 回答
3

这听起来像是Forks::Super::bg_qx.

use Forks::Super 'bg_qx';
$output = bg_qx $bashcommand;
$output1 = bg_qx $bashcommand1;
$output2 = bg_qx $bashcommand2;
$output3 = bg_qx $bashcommand3;

将在后台运行这四个命令。用于返回值的变量($output$output1等)是重载对象。下次在程序中引用这些变量时,您的程序将检索这些命令的输出(如有必要,等待命令完成)。

... more stuff happens ...
# if $bashcommand is done, this next line will execute right away
# otherwise, it will wait until $bashcommand finishes ...
print "Output of first command was ", $output;

&do_something_with_command_output( $output1 );
@output2 = split /\n/, $output2;
...

2012-03-01 更新: Forks::Super 的 v0.60有一些新结构,可让您在列表上下文中检索结果:

if ($condition) {
    tie @output, 'Forks::Super::bg_qx', $bashcommand;
    tie @output1, 'Forks::Super::bg_qx', $bashcommand1;
    tie @output2, 'Forks::Super::bg_qx', $bashcommand2;
    tie @output3, 'Forks::Super::bg_qx', $bashcommand3;
}
...
于 2012-02-06T20:41:36.797 回答
2

你可以,但不能使用反引号。

相反,您需要为它们打开真实的文件句柄open(handle, "$bashcommand|");,然后进行适当的select调用以确定哪个具有为您准备好的新输出。这将比您上面的 6 行多得多,但您将能够同时运行它们。

CPAN中有一些类可能已经为您管理了一些复杂性。

于 2012-02-06T19:37:56.753 回答
0

您应该参考Perl 常见问题解答

Proc::Background看起来很有希望。

于 2012-02-06T19:40:32.997 回答