2012-05-21 3 views
2

나는 파이썬으로 서브 프로세스로 호출되어야하는 프로그램을 가지고있다. 이 프로그램은 자바로 작성되었습니다. 그래, 나도 알아 ...프로그램의 표준 출력의 10 %를 잃는 파이썬 서브 프로세스

어쨌든, 나는 모든 프로그램의 출력을 캡처해야합니다.

불행히도 subprocess.popen2 또는 subprocess.Popen을 communicate [0]이라고하면 부 프로세스를 사용할 때 출력 데이터의 약 10 %가 손실됩니다 .PIPE는 stdout에 할당되고, stdout에 할당 된 파일 설명자 (열린 리턴)를 사용합니다.

하위 프로세스의 설명서는 하위 프로세스의 모든 출력을 캡처하려는 경우 subprocess.PIPE를 사용하는 것이 매우 휘발성이라는 것을 분명히 보여줍니다.

저는 현재 pexpect를 tmp 파일로 출력하기 위해 pexpect를 사용하고 있습니다. 그러나 명백한 이유 때문에 영원히 계속됩니다.

디스크 쓰기를 피하기 위해 모든 데이터를 메모리에 보관하고 싶습니다.

어떤 권고든지 환영 받다! 감사!

import subprocess 

cmd = 'java -Xmx2048m -cp "/home/usr/javalibs/class:/home/usr/javalibs/libs/dependency.jar" --data data --input input" 

# doesn't get all the data 
# 
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) 
output = p.communicate()[0] 

OR 
# doesn't get all the data 
# 
fd = open("outputfile",'w') 
p = subprocess.Popen(cmd, stdout=fd, shell=True) 
p.communicate() 
fd.close() # tried to use fd.flush() too. 

# also tried 
# p.wait() instead of p.communicate(), but wait doesn't really wait for the java program to finish running - it doesn't block 

OR 
# also fails to get all the data 
# 
import popen2 
(rstdout, rstdin) = popen2.popen2(cmd) 

예상 출력은 일련의 아스키 라인 (몇 천 개)입니다. 라인은 숫자와 내가 stdout에 훨씬 더 큰 출력 subprocess을 사용했지만 같은 문제를 보지 못했다

0\n 
1\n 
4\n 
0\n 
... 
+5

일부 출력이 stderr에 기록 될 수 있습니까? – Jeremiah

+0

헤이, stdout (표준 오류가 아님)을 캡처하려고합니다. 출력은 숫자와 줄 끝 문자입니다. 모든 아스키 출력을 기대합니다. –

+2

파이썬 코드가 있습니까? – Bittrance

답변

2

라인 문자의 끝을 포함한다. 당신이 보여준 것의 근본 원인을 결론지기는 어렵습니다. 다음 내용을 확인해 보겠습니다.

p.wait()이 적용되지 않습니다. PIPE을 읽을 때 자바 프로그램이 여전히 마지막 10 %를 인쇄 중일 수 있습니다. 당신의 10 %는 PIPE을 읽기 전에

  • 가 충분히 큰 대기 (예를 들어 30 초)을 삽입 나타 않습니다 p.wait() 먼저 바로 얻을?
  • p.wait()이 Java 프로그램에서 차단되지 않을지 의심 스럽습니다. 귀하의 자바 프로그램이 다른 프로그램을 추가로 하위 처리합니까?
  • p.wait()의 반환 값을 확인하십시오. 자바 프로그램이 정상적으로 종료 되었습니까?

문제가되지 당신이 당신의 자바 프로그램에서 제대로 인쇄하는 경우 다음 확인, 당신의 동시성 모델 낳는 경우

    당신이 stdout로 인쇄 자바 프로그램에서 사용하는 어떤 기능
  • ? IOException을 무시하거나 무시합니까?
  • 스트림을 올바르게 플러시 했습니까? 자바 프로그램이 종료 될 때 적절한 플러시없이 마지막 10 %가 버퍼에 남아있을 수 있습니다.
+0

이 곧 돌아올 것이며 jdi의 메모를 약간 읽게 될 것입니다. 감사! –

2

실제적으로 호출하는 프로세스와 관련이 있어야합니다. 라인을 에코하는 다른 파이썬 스크립트를 사용하여 간단한 테스트를 수행하여이를 확인할 수 있습니다.

out.평

import sys 

for i in xrange(5000): 
    print "%d\n" % i 

sys.exit(0) 

test.py

import subprocess 

cmd = "python out.py" 
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) 
output = p.communicate()[0] 

print output 

그래서 당신은 확인할 수 있습니다 문제가 아니라 당신이 호출하는 프로세스와의 통신되는 데이터의 그것하지 크기.

Popen의 내부 버퍼에 관한 이전의 문제를 읽었으므로 실행중인 python의 버전도 확인해야합니다. (일반적으로 제안 된대로 별도의 파일 핸들을 사용합니다.)

서브 프로세스 호출이 무기한 정지되는 경우 버퍼 문제 일 수 있습니다. 그러나 프로세스가 완료되면, 단지 라인이 부족하면 Popen은 그 일을하고 있습니다.

+0

나는 약간의 회전을주고, 결과를 게시 할 것이다, 고마워! –

관련 문제