2010-06-03 6 views
6

Programları zaman aşımıyla çalıştırmak için perl'de bir komut dosyası oluşturdum. Yürütülmekte olan program daha uzun sürerse, komut dosyası zaman aşımı bu programı öldürür ve "ZAMAN AŞIMI" mesajını döndürür.Çatal yürütme ile ilgili sorun, çıktıyı perl olarak yeniden yönlendirirken öldürme

Çalıştırılan programın çıktısını yeniden yönlendirmeye karar verene kadar betik gayet iyi çalıştı.

Stdout ve stderr yönlendirildiğinde, komut dosyası tarafından yürütülen program, çataldan aldığımdan farklı bir pid'e sahip olduğu için öldürülmez.

Perl, yeniden yönlendirme durumunda programımı yürüten bir kabuk yürütüyor gibi görünüyor.

Çıktı yönlendirmesini almak istiyorum ancak yine de zaman aşımı durumunda programı öldürebilirim.

Bunu nasıl yapabileceğimiz hakkında bir fikriniz var mı?

Senaryomun basitleştirilmiş kod şudur: Herhangi bir yardım için

#!/usr/bin/perl 

use strict; 
use warnings; 
use POSIX ":sys_wait_h"; 

my $timeout = 5; 
my $cmd = "very_long_program 1>&2 > out.txt"; 

my $pid = fork(); 
if($pid == 0) 
{ 
    exec($cmd) or print STDERR "Couldn't exec '$cmd': $!"; 
    exit(2); 
} 
my $time = 0; 
my $kid = waitpid($pid, WNOHANG); 
while ($kid == 0) 
{ 
    sleep(1); 
    $time ++; 
    $kid = waitpid($pid, WNOHANG); 
    print "Waited $time sec, result $kid\n"; 
    if ($timeout > 0 && $time > $timeout) 
    { 
     print "TIMEOUT!\n"; 
     #Kill process 
     kill 9, $pid; 
     exit(3); 
    } 
} 

if ($kid == -1) 
{ 
    print "Process did not exist\n"; 
    exit(4); 
} 
print "Process exited with return code $?\n"; 
exit($?); 

teşekkürler. daha ziyade bir çocuk olarak very_long_program çalışan yerine, very_long_program kendini değiştirmeyi Perlde tarafından olurken alır kabuk söyleyecektir

my $cmd = "exec very_long_program 1>&2 > out.txt"; 

exec için

my $cmd = "very_long_program 1>&2 > out.txt"; 

den $cmd değişen

cevap

11

deneyin.

(Bu durumda bir kabukun sebebi nedir? $cmd, yönlendirme karakterlerini içerir ve perl, bunların nasıl işleneceğini bilmez. Sorunun çözümü için alternatif bir yöntem, yeniden yönlendirme işlemini perl'in kendisinden sonra yapmaktır. fork() ama exec() aramadan önce - ama bu biraz yanıltıcıdır, bu yüzden ilk exec geçici çözümü deneyin)

+0

! Zeki, temiz ve çalışıyor. Tks. – Edu

2

alternatif çatal sonra STDOUT ve STDERR yönlendirmek ve yönlendirme olmadan komutunu çalıştırmaktır:

open(STDOUT, ">", "out.txt") or die "Err: $!"; 
open(STDERR, ">&STDOUT"); 
exec("very_long_command"); 
die "Failed to exec very_long_command: $!"; 
İlgili konular