Мой 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
. Но это не так! Приведенный выше скрипт ничего не выводит.
Есть идеи, как это сделать правильно? (Исправление глючной внешней программы не вариант.) Заранее спасибо.