2009-03-06 5 views
2

gzip, uuencode 및 표준 출력에 필요한 데이터가 있습니다. 내가 기본적으로 가지고있는 것은 :스트림 및 다중 프로세스를 닫는 Python Popen

compressor = Popen("gzip", stdin = subprocess.PIPE, stdout = subprocess.PIPE) 
encoder = Popen(["uuencode", "dummy"], stdin = compressor.stdout) 

나는 압축기에 데이터를 보내는 방법은 compressor.stdin.write (stuff)를 통해서이다.

내가 정말로해야 할 일은 압축기에 EOF를 보내는 것입니다. 어떻게해야할지 모르겠습니다.

언젠가는 compressor.stdin.close()를 시도했지만 작동하지 않습니다. 압축기가 파일에 직접 기록 할 때 제대로 작동하지만 위의 경우 프로세스가 종료되지 않고 compressor.wait()에서 멈 춥니 다.

제안 사항? 이 경우, gzip은 예제이며 한 프로세스의 출력을 다른 프로세스로 파이핑하여 실제로 처리해야합니다.

참고 : 압축해야하는 데이터는 메모리에 맞지 않으므로 의사 소통은 실제로 좋은 옵션이 아닙니다. 또한, 난 그냥 위의 2 선 이후

compressor.communicate("Testing") 

을 실행하면, 여전히 ZLIB 사용을 고려 오류

 
    File "/usr/lib/python2.4/subprocess.py", line 1041, in communicate 
    rlist, wlist, xlist = select.select(read_set, write_set, []) 
+0

cobbal의 대답은 gzip에서 작동하지만 실제로는 그냥 예입니다. – bsdfish

답변

4

내가 파이프를 여는 순서에 문제가 있다고 생각됩니다. UUEncode는 우연히 들어오는 파이프가 없다면 우습게 들릴 것입니다 (Popen 호출에서 storn과 stdout으로 PIPE로 폭발물을 볼 수 있습니다)

이 시도 :

encoder = Popen(["uuencode", "dummy"], stdin=PIPE, stdout=PIPE) 
compressor = Popen("gzip", stdin=PIPE, stdout=encoder.stdin) 

compressor.communicate("UUencode me please") 
encoded_text = encoder.communicate()[0] 
print encoded_text 

begin 644 dummy 
F'XL(`%]^L$D``PL-3<U+SD])5<A-52C([email protected]`;2O+"!(````` 
` 
end 

자네 말이 맞아, BTW ... 파이프를 일반적인 EOF를 보낼 수있는 방법은 없습니다. 결국, 각 프로그램은 실제로 자체 EOF를 정의합니다. 그것을하는 방법은하려고했던 것처럼 파이프를 닫는 것입니다.

편집 : 나는 uuencode에 대해 분명히해야합니다.쉘 프로그램으로서 콘솔 입력을 기대하는 것이 기본 동작입니다. "라이브"수신 파이프없이 실행하면 콘솔 입력을 기다리는 것을 차단합니다. 엔코더를 두 번째로 열면 압축기 파이프 아래로 재료가 보내지기 전에 인코더가 사용자가 입력을 기다리는 것을 차단하고있었습니다. Jerub은 뭔가 막힌 것이 있다는 점에서 옳았습니다.

+0

불행히도 불행히도 전체 출력을 메모리에 저장해야합니다. stdout 인코더가 여전히 걸려있는 것처럼 보입니다. – cobbal

+0

communications()을 사용하면 stdout을 읽지 않아도됩니다. stdout 내용은 통신 명령의 stdin과 함께 터플로 리턴됩니다. 두 파이프 모두에서 쓰기 및 읽기를 사용하도록 변경할 수 있지만 파이썬 문서가 조언하는 monkut의 주석을 참조하십시오. –

+0

거대한 데이터가있는 경우 임시 파일을 사용하여 쉘 프로세스간에 통신하는 것이 가장 좋을까요? –

1

그냥 압축하고 싶은 파일 래퍼를 필요로하지 않는 경우에 중단 모듈

import zlib 
compressed = zlib.compress("text") 

셸 = True 및 유닉스 파이프 제안이 작동하지 않는 이유는 무엇입니까?

from subprocess import * 

pipes = Popen("gzip | uuencode dummy", stdin=PIPE, stdout=PIPE, shell=True) 
for i in range(1, 100): 
    pipes.stdin.write("some data") 
pipes.stdin.close() 
print pipes.stdout.read() 

이 당신이 파이썬에서 직접 일을해야 물건의 종류 아닙니다

3

을 작동하는 것 같다, 그것을 쉘이 할 수있는 더 나은 아이디어를 만드는 방법 것은 작업에 대한 기행이있다 . 당신은 단지 subprocess.Popen ("foo | bar", shell = True)을 사용할 수 있습니다.

gzip이 아직 모든 입력을 출력 할 수 없었으며 stdout 쓰기가 완료 될 때까지 프로세스가 종료되지 않습니다.

strace를 사용하는 경우 프로세스가 어떤 시스템 호출을 차단하는지 확인할 수 있습니다. ps auxwf을 사용하여 어떤 프로세스가 gzip 프로세스인지 알아 낸 다음 strace -p $pidnum을 사용하여 수행중인 시스템 호출을 확인하십시오. stdin은 FD 0이고 stdout은 FD 1입니다. 아마도이 파일 디스크립터에서 읽거나 쓰는 것을 볼 수 있습니다.

관련 문제