2009-08-01 18 views
16

मैं लूप में कमांड लाइन कमांड की एक श्रृंखला चलाने के लिए रूबी में IO.popen का उपयोग कर रहा हूं। मुझे फिर लूप के बाहर एक और कमांड चलाने की जरूरत है। लूप के बाहर का आदेश तब तक नहीं चल सकता जब तक कि लूप में सभी आदेश समाप्त नहीं हो जाते हैं।IO.popen का उपयोग करने की प्रक्रिया को समाप्त करने के लिए कैसे प्रतीक्षा करें?

मैं इस कार्यक्रम को होने के लिए कैसे इंतजार कर सकता हूं? फिलहाल अंतिम आदेश बहुत जल्द चल रहा है।

एक उदाहरण:

for foo in bar 
    IO.popen(cmd_foo) 
end 
IO.popen(another_cmd) 

तो सब cmd_foos से पहले another_cmd चलाया जाता है वापस जाने के लिए की जरूरत है।

उत्तर

4

मुझे लगता है कि आप चर के चक्र के भीतर IO.popen कॉल से परिणाम असाइन करें और जब तक eof() सब पर सच हो जाता है उन पर read() बुला रखने की जरूरत होगी।

तब आप जानते हैं कि सभी कार्यक्रमों ने अपना निष्पादन पूरा कर लिया है और आप another_cmd शुरू कर सकते हैं।

+2

बस एक अतिरिक्त नोट के रूप में आई ओ तरीकों में से ब्लॉक प्रपत्र का उपयोग आमतौर पर सुरक्षित है। इसके अलावा, 1.9 में आपको मजबूती मिलती है क्योंकि ब्लॉक वैरिएबल में अलग-अलग स्कोपिंग होती है जो ब्लॉक के बाहर समान नामित चर के संशोधन को रोकती है (और आप एक चेतावनी अर्जित करेंगे)। –

6
for foo in bar 
    out = IO.popen(cmd_foo) 
    out.readlines 
end 
IO.popen(another_cmd) 

आउटपुट को एक चर में पढ़ने के बाद out.readlines पर कॉल करना। मुझे लगता है कि out.readlines को लौटने से पहले प्रक्रिया समाप्त होने की प्रतीक्षा करनी चाहिए।

सही दिशा में मुझे इंगित करने के लिए एंड्रयू वाई को क्रेडिट।

+0

मैंने एक ही चीज़ की कोशिश की और ज़ोंबी (निष्क्रिय) के साथ समाप्त हो गया, इसलिए आदर्श – nhed

+0

यह अनुपलब्ध नहीं है। –

3

मैं सुझाव है कि आप Thread.join का उपयोग पिछले popen कॉल सिंक्रनाइज़ करने के लिए:

t = Thread.new do 
    for foo in bar 
     IO.popen(cmd_foo) 
    end 
end 

t.join 

IO.popen(another_cmd) 
1

आप popen के उत्पादन की जरूरत है? यदि नहीं, तो क्या आप Kernel#system या कुछ अन्य कमांड का उपयोग करना चाहते हैं?

18

ब्लॉक फार्म का उपयोग करें और सभी सामग्री पढ़ें:

IO.popen "cmd" do |io| 
    # 1 array 
    io.readlines 

    # alternative, 1 big String 
    io.read 

    # or, if you have to do something with the output 
    io.each do |line| 
    puts line 
    end 

    # if you just want to ignore the output, I'd do 
    io.each {||} 
end 

आप उत्पादन पढ़ा नहीं है, तो यह हो सकता है कि इस प्रक्रिया को रोकता है क्योंकि पाइप अन्य प्रक्रिया को जोड़ने और अपने प्रक्रिया पूर्ण और कोई भी नहीं है इससे पढ़ता है।

+0

'iO.popen (' cmd ') होगा। Stdout को हटाते समय बंद करें? डॉक्स का कहना है कि यह '$? 'सेट करता है (इस प्रकार प्रतीक्षा करता है), लेकिन मुझे यह स्पष्ट नहीं है कि यह बिना किसी अवरोध के सभी स्टडआउट को भी हटा देता है। –

+0

"stdout को छोड़कर" का क्या मतलब है? जो कोड आप दिखाते हैं वह कुछ भी त्याग नहीं करता है। अगर आप कुछ निष्पादित करना चाहते हैं और आउटपुट सिस्टम() के साथ विशेष कुछ भी नहीं करना चाहते हैं, तो –

+0

"स्टैडआउट छोड़ दें" से मेरा मतलब है "आउटपुट पढ़ें", जो इस उत्तर में कहा गया है कि अवरोध को रोकने के लिए आवश्यक हो सकता है। –

16

जाहिर है यह करने के लिए canonical way है:

Process.wait(popened_io.pid) 
+0

यह उत्तर सबसे सही है। कोई दुष्प्रभाव नहीं (जैसे io.read के साथ), और यह बहुत स्पष्ट है कि यह क्या कर रहा है। – siannopollo

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

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