我的Perl腳本運行一個外部程序(它接受一個命令行參數)並處理它的輸出。本來,我這樣做:殺死一個懸掛的子進程
my @result = `prog arg`;
然而,事實證明,該方案是越野車,並在極少數情況下不可預知掛起。如果程序在一段時間後還沒有退出,我該如何殺死該程序?該腳本必須在Windows和Linux中都能正常工作,而且我的理解是,警報和分支在Windows中不能很好地運行(或完全不起作用)。
我發現了一個名爲IPC::Run的模塊,但我無法弄清楚如何正確使用它的文檔。 :-(我嘗試這樣做:
use strict;
use warnings;
use IPC::Run qw(run timeout);
my $in;
my $out;
my $err;
my @result;
my @cmd = qw(prog arg);
run \@cmd, \$in, \$out, \$err, timeout (10) or die "@cmd: $?";
push @result, $_ while (<$out>);
close $out;
print @result;
作爲一個測試,我創建了一個程序,只是睡覺60秒打印字符串stdout
並退出當我嘗試使用上面的代碼運行它,它掛起。 60秒(而不是10秒,如超時規定),並與一個奇怪的錯誤中止:
IPC::Run: timeout on timer #1 at C:/Bin/Unix/Perl/site/lib/IPC/Run.pm line 2956
然後我發現了另一個模塊,Proc::Reliable從描述,似乎做的正是我想要的。除了它不起作用!我試過這個:
use strict;
use warnings;
use Proc::Reliable;
my $proc = Proc::Reliable->new();
$proc->maxtime (10);
my $out = $proc->run ("prog arg");
print "$out\n";
它確實會在10秒後中止子進程。到現在爲止還挺好。但後來我修改了外部程序,並讓它只睡5秒鐘。這意味着程序應該在上述代碼中指定的10秒超時之前完成,並且其輸出應該被捕獲到變量$out
中。但事實並非如此!上面的腳本不輸出任何東西。
任何想法如何正確地做到這一點? (修復有問題的外部程序不是一個選項。)在此先感謝。
您是否嘗試過從Reliable對象打印stderr,status和msg的輸出? – Nick 2012-02-22 15:47:38
當你設置調試時會發生什麼? 'Proc :: Reliable :: debug($ level);' – DVK 2012-02-22 15:49:08
如果我執行'Proc :: Reliable :: debug(1);',腳本只輸出'Proc :: Reliable> ATTEMPT 0:'prog arg''沒有別的。 '$ out'沒有輸出。 (當然,如果我手動運行'prog arg'程序,我會得到輸出。) – Vess 2012-02-22 16:43:51