2012-08-30 11 views
9

कहें कि मेरे पास एक कार्य है, मैं प्रोसेस.स्पॉन कॉल के आउटपुट को कैप्चर कैसे करूं? यदि प्रक्रिया निर्दिष्ट समय सीमा से अधिक समय लेती है तो मुझे प्रक्रिया को मारने में भी सक्षम होना चाहिए।टाइमआउट और कैप्चर आउटपुट के साथ फोर्क बाल प्रक्रिया

ध्यान दें कि फ़ंक्शन क्रॉस-प्लेटफ़ॉर्म (विंडोज/लिनक्स) भी होना चाहिए।

def execute_with_timeout!(command) 
    begin 
    pid = Process.spawn(command)  # How do I capture output of this process? 
    status = Timeout::timeout(5) { 
     Process.wait(pid) 
    } 
    rescue Timeout::Error 
    Process.kill('KILL', pid) 
    end 
end 

धन्यवाद।

उत्तर

12

आप IO.pipe का उपयोग कर सकते हैं और बाहरी मणि की आवश्यकता के बिना पुनर्निर्देशित आउटपुट का उपयोग करने के लिए Process.spawn बता सकते हैं।

बेशक

, केवल रूबी 1.9.2 के साथ शुरू (और मैं व्यक्तिगत रूप से 1.9.3 सलाह देते हैं)

निम्नलिखित एक सरल Spinach BDD आंतरिक द्वारा इस्तेमाल किया दोनों बाहर कब्जा और आउटपुट गलती करना दिया गया है:

# stdout, stderr pipes 
rout, wout = IO.pipe 
rerr, werr = IO.pipe 

pid = Process.spawn(command, :out => wout, :err => werr) 
_, status = Process.wait2(pid) 

# close write ends so we could read them 
wout.close 
werr.close 

@stdout = rout.readlines.join("\n") 
@stderr = rerr.readlines.join("\n") 

# dispose the read ends of the pipes 
rout.close 
rerr.close 

@last_exit_status = status.exitstatus 

मूल स्रोत अत्यधिक की सिफारिश की है आप पढ़ सकते हैं रूबी की अपनी Process.spawn प्रलेखन features/support/filesystem.rb

में है।

उम्मीद है कि इससे मदद मिलती है।

पीएस: मैंने टाइमआउट कार्यान्वयन को आपके लिए होमवर्क के रूप में छोड़ा ;-)

+0

बिल्कुल सही! वास्तव में मेरे समाधान के मुकाबले मैं और अधिक सुरुचिपूर्ण था :) – thegreendroid

+0

उस कोड में '_,' मतलब क्या है? –

+3

@TamerShlash 'Process.wait2' प्रलेखन को पढ़ता है, यह एक tuple (दो मान) देता है, और हम एक को' स्थिति 'को आवंटित करते हैं और दूसरा (पहला वाला) _ को असाइन किया जाता है, जो सामान्य अभ्यास है जब आप त्यागना चाहते हैं एक मूल्य –

3

मैंने रुबी फोरम here पर अपनी पोस्ट में एन्सल्म की सलाह का पालन किया।

समारोह इस तरह दिखता है -

def execute_with_timeout!(command) 
    begin 
    pipe = IO.popen(command, 'r') 
    rescue Exception => e 
    raise "Execution of command #{command} unsuccessful" 
    end 

    output = "" 
    begin 
    status = Timeout::timeout(timeout) { 
     Process.waitpid2(pipe.pid) 
     output = pipe.gets(nil) 
    } 
    rescue Timeout::Error 
    Process.kill('KILL', pipe.pid) 
    end 
    pipe.close 
    output 
end 

यह काम करता है, लेकिन मैं नहीं बल्कि एक तीसरे पक्ष के मणि कि यह कार्यक्षमता लपेटता का उपयोग करेंगे। किसी के पास ऐसा करने का कोई बेहतर तरीका है? मैंने Terminator की कोशिश की है, यह वही करता है जो मैं चाहता हूं लेकिन यह विंडोज पर काम नहीं कर रहा है।

संबंधित मुद्दे