2016-06-03 3 views
0

나는 여러 단계의 프로세스를 거쳤습니다. 기본적으로, stdout을 한 파일에 쓰고 (다음 단계로 넘어 가기 위해) subprocess.call (또는 이와 동등한 것)을 호출하여 stdout과 stderr를 적절하게 시간순으로 다른 파일에 씁니다. 사용자).파이썬 하위 프로세스가 파일간에 임의로 출력을 분할합니다.

나는이 같은 서명으로 함수를 작성 할 수 있어야한다 : (I가 임시 파일로 작업 할 수 있지만, 바람직하게 파일 같은 객체) 후자의 두 인수는 파일입니다

def CallProcess(command, outonlyfile, interleavedfile) 

등 그것은해야

foo: 
out1 
out2 

bar: 
out1 
err1 
out2 
err2 

: 출력

import tempfile 

foo = tempfile.TemporaryFile('wb+') 
bar = tempfile.TemporaryFile('wb+') 

CallProcess('echo out1; echo err1 >&2; echo out2; echo err2 >&2', foo, bar) 
foo.seek(0) 
bar.seek(0) 

print('foo:') 
print(foo.read()) 
print() 
print('bar:') 
print(bar.read()) 

을 그리고 그것은해야 : 난 너무로 호출 할 수 플랫폼에 구속력이 없으므로 (tee 또는 그와 같은 전화를 걸 수 없음) 그것은 바람직하게 순수한 파이썬이어야합니다.

여러 개의 파일 핸들을 출력하는 Tee 오브젝트를 생성 해 보았습니다.하지만 불행히도 subprocess.call은 파일과 같은 오브젝트를 허용하지 않고 실제 파일 만 허용합니다.

답변

0

어떤 운영 체제에서든 stderrstdout에 쓰는 모든 하위 프로세스에 대해 일반적으로 해결할 수있는 문제는 아닌 것으로 생각합니다. 근본적인 문제는 stdoutstderr이 시스템 수준에서 독립적이라는 것입니다.

는 다음과 같은 코드를 가지고 말 :

아이 :

import sys 
sys.stdout.write('stdout line 1') 
sys.stderr.write('stderr line 2') 

부모 :

# parent process is using select to wait for data on the pipes it set 
# up to communicate with the child 
readable_fds = select([child.stdout, child.stderr]) 
당신은 child.stdout은 그것이 비록 child.stderr 전에 데이터를 사용할 수있을 것이라는 점을 보장 할 수 없습니다

먼저 child.stdout에 기록됩니다.

다음과 같은 스크립트를 사용하면 쉽게 데이터를 볼 수 있습니다. 데이터가 동시에 둘 모두에 표시되는 경우 어느 것이 먼저 쓰여졌는지 어떻게 알 수 있으며 처음에는 stderr에 나타날 수 있다는 것이 불가능하지 않습니다. 대부분의 로그는 각 로그 메시지의 도착 타임 스탬프를 가지고 당신이 나중에 편집기에서 별도의 파일에 stdoutstderr을 넣고 중 하나를 비교할 수 방법을 참조하거나 일부 사후 처리를 할 수 있습니다 이유

from select import select 
from subprocess import Popen, PIPE 

while True: 
    child = Popen('echo hello; echo goodbye>&2', shell=True, stdout=PIPE, stderr=PIPE) 
    rfs, _, _ = select([child.stdout, child.stderr], [], []) 
    child.wait() 
    if len(rfs) > 1: 
     print('Data available on both pipes simultaneously! Cannot interleave correctly.') 
     break 

의 그 그들을 재결합하십시오.

또는 자식 프로세스에 라이브러리를 삽입하면 stdout/stderr 호출에 대한 인터셉트를 가로 채고 올바르게 인터리브 할 수 있습니다.

+0

그래, 그럴 필요가 있을지 모르겠다. 나는 깨끗한 해결책을 원했다. 감사. – Taywee

관련 문제