2012-05-19 1 views
9

체인의 첫 번째 과정에서 진정한 쉘을 = 사용하면 어떻게 든 다운 스트림 작업의 표준 출력 떨어질 것 같다 ... 첫 번째 프로세스의 사용 쉘을 만들기쉘이 True이면 내 서브 프로세스를 먹지 않습니다. 표준 출력을 엽니 다.

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) 

shell = 두 번째 프로세스에서 true는 중요하지 않습니다. 이 예상되는 동작입니까?

답변

15

shell=True을 전달할 때 Popen은 목록이 아닌 단일 문자열 인수를 필요로합니다. 그래서 당신은이 작업을 수행 할 때

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

감사합니다! 후자를 위해, 다음은 [docs] (http://docs.python.org/library/subprocess.html)입니다 : 쉘에서 = True : 추가 항목은 셸 자체에 대한 추가 인수로 처리됩니다. 즉, Popen은 다음과 같은 것을 수행합니다 : 'Popen ([ '/ bin/sh', '-c', args [0], args [1], ...])' –

+0

은 매우 잘 문서화되지 않았습니다. IMHO – Davide