2012-04-18 12 views
0

유닉스와 윈도우에서 똑같이 잘 작동하는 Python 2 *의 getstatusoutput() 함수에 대한 위대한 대체품을 발견했습니다. 그러나, 나는 output이 구성되는 방식에 문제가 있다고 생각합니다. 출력의 마지막 줄만 반환하지만 그 이유는 알 수 없습니다. 어떤 도움이라도 굉장합니다.Python getstatusoutput 대체가 전체 출력을 반환하지 않음

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell.""" 
    """This new implementation should work on all platforms.""" 
    import subprocess 
    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True) 
    output = "".join(pipe.stdout.readlines()) 
    sts = pipe.returncode 
    if sts is None: sts = 0 
    return sts, output 
+0

try 블록 내에서'subprocess.check_call '을 사용하지 않는 이유는 무엇입니까? 'except' 부분에서 리턴 코드 (0이 아닌 경우)를 얻을 수 있습니다. – wim

+0

반환 코드가 0 인 경우에도 출력을 원한다면 어떻게해야합니까? – MFB

답변

2

버그가 있습니다.

호출 : 공정 오프

pipe = subprocess.Popen(...) 

차기. 라인 :이 먹통 얻을 수있는 오류 출력이 있다면

output = "".join(pipe.stdout.readlines()) 

은 (프로세스의 표준 출력을 읽고,하지만 당신은 표준 오류 리디렉션하지 않았기 때문에이 안전, 더 일반적인 경우에, 당신은 .communicate() 기능을 사용할 필요가 가능한 쐐기를 피하기 위해). 생각할 수도 있습니다. 음, 모든 출력을 읽었으므로 하위 프로세스가 분명하게 끝났으므로 pipe.returncode을 설정해야합니다. 그러나 사실, 당신이 경우 대체 :

sts = pipe.returncode 
if sts is None: sts = 0 

을 어떤 종류의 진단을 포함 (또는 완전히 두 번째 줄 삭제) 코드, 당신은 sts은, 적어도 때때로 일부 시스템에서, 그것을 찾을 수 있습니다로None. 그 이유는 subprocess 모듈이 아직 모듈을 검색 할 기회가 없었기 때문입니다. 결과를 수집하고 is None 테스트의 필요성을 미연에 방지하기 위해

sts = pipe.wait() 

: 당신과 함께 그 라인을 교체해야합니다. (그것은 당신이 .communicate()을 사용 및/또는 이미 .wait()라고 한 경우에도 .wait() 전화 안전합니다.)

"".join(...) 그냥 사용하여보다 효율적으로 경미하게 수행 할 수 있습니다

output = pipe.stdout.read() 

말했다 모든, 그것은 않습니다 나를 위해 완전한 결과를 얻으십시오. 어쩌면 당신은 newline을 위해서 '\r'을 사용하고 파이썬은 universal-newline을 지원하지 않고 만들어 졌을 것입니다. (\r -for-newline을 생성하는 프로그램을 실행하면 실제 줄 바꿈으로 구분 된 모든 줄이 나타납니다.)

+0

이 우수한 설명에 감사드립니다. 나는 이미 많은 것을 배웠다. 그러나, 당신은 개행과 관련이 있다고 생각합니다. 나는 단지 내 기능에서''\ n ''을 다시 얻고있다. 개행 문제를 확대 할 수 있습니까? – MFB

+0

[docs] (http://docs.python.org/library/functions.html#open)에서 "universal newline"은 입력 스트림을 읽을 때 입력 스트림이 일반 " \ r' 또는'\ r \ n' 또는 일반'\ n'은 파이썬을 단순한'\ n' 문자를 "보게"만듭니다. 그러나이를 위해서는 Python을 지원해야합니다. 그렇지 않다면, 평범한'\ r'은'\ r'로 보이고 결과 문자열을'print'하면 모든 것이 보이지 않을 수도 있습니다. 예 :'>>> print 'something \ relse'' *는'elsething'을 출력합니다. – torek

+0

그건 의미가 있지만,'\ n'을 섞어서 모든 결과를 얻지 않아야합니까? 대신에 서브 프로세스 (이 경우 ffmpeg)가 더 많은 것을 출력하고 있음을 알았을 때에도 단순히 ''\ n ''을 얻고 있습니다. – MFB

관련 문제