现在我有一个perl脚本,在某个时刻,收集然后处理几个bash命令的输出,现在我就是这样做的:
if ($condition) {
@output = `$bashcommand`;
@output1 = `$bashcommand1`;
@output2 = `$bashcommand2`;
@output3 = `$bashcommand3`;
}
问题是,这些命令中的每一个都需要相当长的时间,因此,我想知道我是否可以同时运行它们。
答案 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看起来很有希望。