2012-05-19 10 views
9

Bir zincirin ilk süreçte Gerçek shell = kullanarak nasılsa mansap görevleri stdout'u düşer gibi görünüyor: ... İlk süreç kullanımı kabuğu yapmaNeden kabuk = True alt süreçimi kullanıyor. Pop-up stdout?

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

= Doğru bir şekilde çıkışını öldürür

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

Kabuk = İkinci işlemde doğru görünmüyor. Bu beklenen davranış mı?

cevap

15

Popen, shell=True'u geçtiğinizde, bir liste değil, tek bir dize argümanı bekler. Böylece bunu yaparken:

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

Ne olur şu: olup

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

, bu sh -c "echo" çağırır ve hello etkili bir ihmal edilir (Teknik olarak kabuk bir pozisyonel argüman haline gelir). Bu nedenle, kabuk \n'u yazdıran echo'u çalıştırır, bu yüzden çıktınızda bunu görüyorsunuz. Eğer shell=True kullanırsanız

, bunu yapmak gerekir:

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

Teşekkür! Gelecek kuşak için, [docs] (http://docs.python.org/library/subprocess.html): On Unix'te, shell = True: Eğer bir satırlar bir satır ise, ilk öğe komut dizesini belirtir, ve ek öğeler kabuğun kendisine ek argümanlar olarak ele alınacaktır. Yani, Popen eşdeğer: 'Popen (['/ bin/sh', '-c', args [0], args [1], ...])' –

+0

çok zayıf bir şekilde belgelenmiş, Benim nacizane fikrime göre – Davide

İlgili konular