【发布时间】:2012-03-12 23:11:27
【问题描述】:
我的 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 秒超时之前完成,并且它的stdout 输出应该被捕获到变量$out 中。但事实并非如此!上面的脚本没有输出任何东西。
任何想法如何正确地做到这一点? (修复有缺陷的外部程序不是一种选择。)提前致谢。
【问题讨论】:
-
您是否尝试过从 Reliable 对象打印 stderr、status 和 msg 的输出?
-
设置调试时会发生什么?
Proc::Reliable::debug($level); -
如果我执行
Proc::Reliable::debug (1);,脚本只会输出Proc::Reliable> ATTEMPT 0: 'prog arg',没有别的。$out没有输出。 (当然,如果我手动运行程序prog arg,我确实会得到输出。)
标签: perl perl-module