2010-06-03 7 views
6

में आउटपुट रीडायरेक्ट करते समय फोर्क निष्पादन की समस्या के साथ समस्या मैंने टाइमआउट के साथ प्रोग्राम चलाने के लिए पर्ल में एक स्क्रिप्ट बनाई है। यदि प्रोग्राम को निष्पादित किया जा रहा है तो स्क्रिप्ट की तुलना में टाइमआउट इस कार्यक्रम को मारता है और "TIMEOUT" संदेश देता है।पर्ल

स्क्रिप्ट तब तक काफी अच्छी तरह से काम करती है जब तक कि मैंने निष्पादित प्रोग्राम के आउटपुट को रीडायरेक्ट करने का निर्णय नहीं लिया।

जब स्टडआउट और स्टडर को रीडायरेक्ट किया जा रहा है, तो स्क्रिप्ट द्वारा निष्पादित कार्यक्रम को मार नहीं दिया जा रहा है क्योंकि इसमें एक कांटा से मुझे एक पिड अलग है।

ऐसा लगता है कि पर्ल एक शेल निष्पादित करता है जो पुनर्निर्देशन के मामले में मेरे कार्यक्रम को निष्पादित करता है।

मैं आउटपुट रीडायरेक्शन करना चाहता हूं लेकिन फिर भी टाइमआउट के मामले में प्रोग्राम को मारने में सक्षम हूं।

कोई विचार है कि मैं इसे कैसे कर सकता हूं?

मेरी स्क्रिप्ट का एक सरलीकृत कोड है:

#!/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($?); 

किसी भी मदद के लिए धन्यवाद।

उत्तर

11

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

से $cmd बदलते

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

exec को खोल कि पर्ल द्वारा पैदा की हो जाता है बल्कि एक बच्चे के रूप very_long_program चलाने की तुलना में, very_long_program साथ ही बदलने के लिए बता देंगे की कोशिश।

(कारण इस मामले में एक शेल स्पंज करता है क्योंकि $cmd में रीडायरेक्ट वर्ण होते हैं - और पर्ल को यह नहीं पता कि उन्हें स्वयं कैसे संभालना है। समस्या को हल करने का एक वैकल्पिक तरीका है पर्दे में खुद को पुनर्निर्देशन करना fork() लेकिन exec() बुला से पहले - लेकिन यह है कि थोड़ा जटिल है, तो पहले exec वैकल्पिक हल की कोशिश)

+0

! चालाक, साफ और काम करता है। टी.के.एस। – Edu

2

एक वैकल्पिक कांटा के बाद STDOUT और STDERR अनुप्रेषित और पुनर्निर्देशन बिना आदेश को चलाने के लिए है:

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