Matar um processo filho pendurado
script @My Perl executa um programa externo (que usa um único parâmetro de linha de comando) e processa sua saída. Originalmente, eu estava fazendo isso:
my @result = `prog arg`;
No entanto, o programa é com erros e trava imprevisivelmente em casos raros. Como posso matar o programa se ele não sair após um certo período de tempo? O script deve funcionar tanto no Windows quanto no Linux, e entendo que alarmes e bifurcações não funcionam bem (ou nada) no Window
Encontrei um módulo chamadoIPC :: Run mas não consigo descobrir como usá-lo corretamente a partir de sua documentação. :-( Eu tentei isso:
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;
Como teste, criei um programa que dorme 60 segundos e imprime uma string parastdout
e sai. Quando tento executá-lo com o código acima, ele fica parado por 60 segundos (em vez de por 10 segundos, conforme especificado no tempo limite) e é interrompido com um erro bizarro:
IPC::Run: timeout on timer #1 at C:/Bin/Unix/Perl/site/lib/IPC/Run.pm line 2956
Encontrei outro módulo,Proc :: Confiável. A partir da descrição, parece fazer exatamente o que eu quero. Exceto que não funciona! Eu tentei o seguinte:
use strict;
use warnings;
use Proc::Reliable;
my $proc = Proc::Reliable->new ();
$proc->maxtime (10);
my $out = $proc->run ("prog arg");
print "$out\n";
Aborta de fato o processo filho após 10 segundos. Por enquanto, tudo bem. Mas então eu modifiquei o programa externo e o fiz dormir por apenas 5 segundos. Isso significa que o programa deve terminar antes do tempo limite de 10 segundos especificado no código acima e seustdout
output deve ser capturado na variável$out
. Mas não é! O script acima não produz nada.
Alguma idéia de como fazê-lo corretamente? (A correção do programa externo de buggy não é uma opção.) Agradecemos antecipadamente.