2012-05-19 10 views
9

ऐसा लगता है कि खोल = एक श्रृंखला की पहली प्रक्रिया में सच का उपयोग कर किसी भी तरह नीचे की ओर कार्यों से stdout चला जाता है:शैल = सच क्यों मेरे उपप्रोसेसर खाते हैं। स्टॉपआउट खोलें?

p1 = Popen(['echo','hello'], stdout=PIPE) 
p2 = Popen('cat', stdin=p1.stdout, stdout=PIPE) 
p2.communicate() 
# outputs correctly ('hello\n', None) 

पहली प्रक्रिया उपयोग खोल बनाना = सच उत्पादन किसी भी तरह मारता है ...

p1 = Popen(['echo','hello'], stdout=PIPE, shell=True) 
p2 = Popen('cat', stdin=p1.stdout, stdout=PIPE) 
p2.communicate() 
# outputs incorrectly ('\n', None) 

खोल = दूसरी प्रक्रिया पर सही कोई फर्क नहीं पड़ता। क्या यह अपेक्षित व्यवहार है?

उत्तर

15

जब आप shell=True पास करते हैं, तो पॉपन एक स्ट्रिंग तर्क की अपेक्षा करता है, सूची नहीं। तो अगर आप ऐसा करते हैं जब:

p1 = Popen(['echo','hello'], stdout=PIPE, shell=True) 

क्या होता है यह है:

execve("/bin/sh", ["/bin/sh", "-c", "echo", "hello"], ...) 

है यही कारण है, यह sh -c "echo" कहता है, और hello प्रभावी रूप से नजरअंदाज कर दिया है (तकनीकी रूप से यह खोल करने के लिए एक स्थितीय तर्क हो जाता है)। तो खोल echo चलाता है, जो \n प्रिंट करता है, यही कारण है कि आप अपने आउटपुट में देखते हैं।

आप shell=True का उपयोग करते हैं, तो आप इस सब करने की ज़रूरत:

p1 = Popen('echo hello', stdout=PIPE, shell=True) 
+3

धन्यवाद! वंशावली के लिए, यहां [डॉक्स] (http://docs.python.org/library/subprocess.html) है: यूनिक्स पर, खोल = सही के साथ: अगर तर्क एक अनुक्रम है, तो पहला आइटम कमांड स्ट्रिंग निर्दिष्ट करता है, और किसी भी अतिरिक्त आइटम को खोल के लिए अतिरिक्त तर्क के रूप में माना जाएगा। यही कहना है, पॉपन बराबर करता है: 'पॉपन (['/बिन/श ',' -सी ', तर्क [0], तर्क [1], ...]) –

+0

बहुत खराब दस्तावेज, IMHO – Davide

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