2011-03-28 2 views
0

그래서 저는 필자가 작성중인 파이썬 응용 프로그램에 하위 프로세스를 사용하는 데 문제가 있습니다. 문제를 설명하기 위해 필자는이 문제를 잘 해결할 수있는 작은 스크립트를 작성했습니다.파이썬 하위 프로세스가 종료되지 않고 출력에서 ​​빈 문자열을 계속 제공합니다.

from __future__ import print_function 

import subprocess as sp 
from select import select 

p = sp.Popen(['ls'], stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) 
p.stdin.close() 

while p.returncode is None or p.stdout.closed or p.stderr.closed: 
    # print('returncode is', p.returncode) 
    available_readers = select([p.stdout, p.stderr], [], [], 2.0)[0] 
    for r in available_readers: 
     print(r.read(1)) 
     # output_display.insert(tk.END, r.read(1)) 

당연히, 우리는 모두 ls 명령 stdout에 몇 가지 물건을 인쇄 한 후 바로 존재 (또는 stderr을 할 수있다) 것을 알고 있지만, 위의 스크립트는 결코 존재하지 않는다.

위 스크립트의 마지막 줄 (주석)에서 알 수 있듯이 하위 프로세스의 내용을 tk 텍스트 구성 요소에 넣어야합니다. 그래서, 나는 실행해야 할 명령으로 .communicate 및 다른 블로킹 호출과 같은 메소드를 사용할 수 없으며 오랜 시간이 걸리므로 출력을 (거의) 실시간으로 표시해야합니다. (Ofcourse, Tk를 실행할 때 별도의 스레드에서 실행해야하지만, 다른 것입니다).

그래서이 스크립트가 종료되지 않는 이유를 이해할 수 없습니다. 빈 문자열을 영원히 계속 인쇄합니다 (ls 명령의 예상 된 출력 이후).

알려 주시기 바랍니다. 나는 우분투 10.10

편집에 파이썬 2.6.6을 실행하고 다음은 조건 중에 해당하는 동안

from __future__ import print_function 

import subprocess as sp 
from select import select 

p = sp.Popen(['ls'], stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) 
p.stdin.close() 

while p.poll() is None: 
    # print('returncode is', p.returncode) 
    available_readers = select([p.stdout, p.stderr], [], [], 2.0)[0] 
    for r in available_readers: 
     print(r.read(1), end='') 
     # output_display.insert(tk.END, r.read(1)) 

print(p.stdout.read(), end='') 
print(p.stderr.read(), end='') 

답변

1
while p.returncode is None or p.stdout.closed or p.stderr.closed: 

루프를 작동 위의 스크립트의 버전입니다. 당신은 아마 단지 returncode (그리고 모든 반복에서 poll)을 검사하기위한 것입니다.

관련 문제