2011-03-04 6 views
12

서브 프로세스 모듈은 2.6 및 3.1에 모두 같이 구현 편의 기능 call파이썬의 subprocess.call이 왜 이렇게 구현 되었습니까?

def call(*popenargs, **kwargs): 
    return Popen(*popenargs, **kwargs).wait() 

이 기능 설명서에 붉은 경고 전달을 읽고 :

경고 : Popen.wait()과 마찬가지로 stdout=PIPE 및/또는 stderr=PIPE을 사용하면 교착 상태가되며 자식 프로세스는 파이프에 충분한 출력을 생성하여 OS 파이프 버퍼가 더 많은 데이터를 받아들이는 것을 차단합니다.

Popen.wait() 설명서에는 이러한 경우 대신 Popen.communicate()이 사용됩니다. 음, 그렇다면 call은 아래처럼 대신 구현되었으므로 어리석은 경고를 제거하고 표준 라이브러리에서 제거한 바보 같은 제한을 없앨 수 있습니까?

def call(*args, **kwargs): 
    input = kwargs.pop("input", None) 
    p = Popen(*args, **kwargs) 
    p.communicate(input) 
    return p.returncode 

확실한 이유가 있습니다. 내가 뭘 놓치고 있니?

답변

8
내가 디자인 결정이 포함 알아 내려고 노력하고, 서브 프로세스 모듈을 도입 PEP-324를 통해 보는 시간을 보냈지 만 나는 대답은 실제로 매우 간단하다 생각

:

stdout=PIPE을 통과 할 이유 없습니다

또는 stderr=PIPE ~ subprocess.call이므로 교착 상태가 발생할 수 있다는 사실은 부적절합니다.

유일한 이유 subprocess.Popenstdout=PIPE 또는 stderr=PIPE 그래서 당신이 파일 객체로는 popen 인스턴스의 stdoutstderr 속성을 사용할 수 있다는 것입니다 전달합니다. subprocess.call은 Popen 인스턴스를 볼 수 없기 때문에 PIPE 옵션은 관련성이 없어집니다.

Popen.communicate (파이프 모니터링을 통해 교착 상태를 피하기 위해 추가 스레드 생성)에 잠재적 인 오버 헤드가 있으며,이 경우 이점이 없으므로 사용할 필요가 없습니다.

편집 : 당신이 의도하지 PIPE 파일에 모든 출력을 캡처하는

# option 1 
with open(os.devnull, 'w') as dev_null: 
    subprocess.call(['command'], stdout=dev_null, stderr=dev_null) 

# option 2 
subprocess.call(['command >& /dev/null'], shell=True) 

을 대신 서브 프로세스를 지시의 : 당신이 당신의 출력을 폐기하려는 경우, 나는 그렇게 명시 적으로 할 더 나은 것 같아요 용도.

+0

프로그램의 출력을 제어하는 ​​것은 stdout = PIPE 및 stderr = PIPE를 사용하는 것입니다. 즉,'command>/dev/null 2> & 1'에 해당하는 python과 bash에서'$? '를 검사합니다. –

+0

'stdout = open ('/ dev/null', 'w'), stderr = STDOUT'으로 더 잘하지 않겠습니까? –

+0

@Baffe 추측하지만, 핵심은'call'의 stdout = 및 stderr = 키워드 인수를 사용해야하는 이유입니다. –

2

명령을 실행하고 종료 상태를 확인하여 성공 또는 실패했는지 확인하려면 파이프를 통해 통신하지 않아도됩니다. 이것이 subprocess.call() 메소드의 편리함입니다. 하위 프로세스 모듈에는 Popen 객체를 효율적으로 사용하는 일반적인 용도 중 많은 것을 캡슐화하는 다른 편리한 함수가 있습니다.

자식 프로세스 stdout 또는 stderr을 call()을 사용하지 않는 곳으로 파이프해야하는 경우 Popen 객체를 사용하고 docs 상태와 마찬가지로 Populate 객체와 통신()합니다.

관련 문제