异步运行perl的反引号

时间:2012-02-06 19:31:05

标签: perl asynchronous backticks

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

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

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

4 个答案:

答案 0 :(得分:4)

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

不幸的是,显然Unix select的Win32仿真无法处理文件I / O,因此要在Windows上启用它,您还必须添加一层套接字I / O,为此{{ 1}}有效,请参阅perlmonks

答案 1 :(得分: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: v0.60 of Forks :: Super has some new constructions,可让您在列表上下文中检索结果:

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;
}
...

答案 2 :(得分:2)

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

相反,您需要使用open(handle, "$bashcommand|");为它们打开实际文件句柄,然后执行正确的select调用以确定哪个具有适合您的新输出。它需要比你上面的6行更多,但你可以同时运行它们。

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

答案 3 :(得分:0)

您应该参考Perl FAQ

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