कैप्चर करते समय चुनिंदा और पीटीआई लटकते हुए उपप्रोसेस का उपयोग करके मैं एक पायथन प्रोग्राम लिखने की कोशिश कर रहा हूं जो अन्य प्रोग्राम्स के साथ बातचीत करने में सक्षम है। इसका मतलब है कि stdin भेजना और stdout डेटा प्राप्त करना। मैं pexpect का उपयोग नहीं कर सकता (हालांकि यह निश्चित रूप से कुछ डिजाइन प्रेरित)।आउटपुट
- एक प्राइवेट उपप्रक्रिया के stdout
- लूप को उपप्रक्रिया बाहर निकलता है जब तक
subprocess.poll
- की जाँच करके संलग्न जब डेटा stdout कि डेटा लिखने में उपलब्ध है: प्रक्रिया मैं अभी उपयोग कर रहा हूँ यह है तुरंत वर्तमान stdout के लिए।
- समाप्त करें!
मैं कुछ कोड (नीचे) प्रोटोटाइप कर रहा हूं जो काम करता है लेकिन ऐसा लगता है कि मुझे एक दोष है जो मुझे परेशान कर रहा है। बाल प्रक्रिया पूरी होने के बाद, यदि मैं select.select
का उपयोग करते समय टाइमआउट निर्दिष्ट नहीं करता हूं तो मूल प्रक्रिया लटकती है। मैं वास्तव में एक टाइमआउट सेट नहीं करना पसंद करूंगा। यह बस थोड़ा गंदा लगता है। हालांकि, इस मुद्दे के आसपास आने के अन्य सभी तरीकों से काम नहीं लगता है। और pty.openpty
के बजाय os.execv
और pty.fork
का उपयोग करके Pexpect इसके आसपास मिल रहा है, जो समाधान मुझे पसंद नहीं है। क्या मैं कुछ गलत कर रहा हूं कि मैं उपप्रजाति के जीवन की जांच कैसे करता हूं? क्या मेरा दृष्टिकोण गलत है?
मैं जिस कोड का उपयोग कर रहा हूं वह नीचे है। मैं इसे मैक ओएस एक्स 10.6.8 पर उपयोग कर रहा हूं, लेकिन मुझे इसे उबंटू 12.04 पर भी काम करने की ज़रूरत है।
import subprocess
import select
import pty
import os
import sys
def main():
master, slave = pty.openpty()
process = subprocess.Popen(['python', 'outputter.py'],
stdin=subprocess.PIPE,
stdout=slave, stderr=slave, close_fds=True)
while process.poll() is None:
# Just FYI timeout is the last argument to select.select
rlist, wlist, xlist = select.select([master], [], [])
for f in rlist:
output = os.read(f, 1000) # This is used because it doesn't block
sys.stdout.write(output)
sys.stdout.flush()
print "**ALL COMPLETED**"
if __name__ == '__main__':
main()
यह उपप्रक्रिया कोड outputter.py
है:
यह उपप्रक्रिया धावक runner.py
है। अजीब यादृच्छिक भाग यादृच्छिक अंतराल पर डेटा आउटपुट करने वाले प्रोग्राम को अनुकरण करने के लिए हैं। यदि आप चाहें तो इसे हटा सकते हैं। यह कोई फर्क नहीं करना चाहिए:
import time
import sys
import random
def main():
lines = ['hello', 'there', 'what', 'are', 'you', 'doing']
for line in lines:
sys.stdout.write(line + random.choice(['', '\n']))
sys.stdout.flush()
time.sleep(random.choice([1,2,3,4,5])/20.0)
sys.stdout.write("\ndone\n")
sys.stdout.flush()
if __name__ == '__main__':
main()
किसी भी मदद के लिए आप सभी प्रदान कर सकते हैं के लिए धन्यवाद!
अतिरिक्त टिप्पणी
Pty प्रयोग किया जाता है, क्योंकि मैं यह सुनिश्चित करें कि stdout बफ़र नहीं है चाहता हूँ।
शानदार स्पष्टीकरण के लिए धन्यवाद। मैंने सोचा, थोड़ी देर के बाद, यह शायद एक टाइमआउट सेट करने के लिए सबसे अच्छा होगा। मैंने इजाक के समाधान की कोशिश की लेकिन हाँ, मैंने ऐसा करने के बाद कुछ अजीब व्यवहार देखा। यह बहुत मदद करता है! – ravenac95
अपने स्वयं के सुधार के लिए, क्या आप समझा सकते हैं कि मेरा जवाब कम क्यों हुआ? यह आपको किसी भी टाइमआउट का उपयोग करने से बचना चाहिए। –
मैंने आपके सुझावों को [संबंधित प्रश्न के उत्तर] में लागू किया है (http://stackoverflow.com/a/12471855/4279) – jfs