문제

GZIP, UUENCODE를하고 인쇄하여 표준으로 인쇄하고 싶은 데이터가 있습니다. 기본적으로 가지고있는 것은 다음과 같습니다.

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

컴프레서에 데이터를 공급하는 방법은 압축기를 통한 것입니다.

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

어느 시점에서 Compressor.stdin.close ()를 시도했지만 작동하지 않습니다. 컴프레서가 파일에 직접 쓸 때 잘 작동하지만 위의 경우 프로세스가 종료되지 않고 압축기가 중단되지 않습니다. 기다리다().

제안? 이 경우 GZIP가 예이며 한 프로세스의 출력을 다른 프로세스로 배관하여 무언가를해야합니다.

참고 : 압축 해야하는 데이터는 메모리에 맞지 않으므로 의사 소통은 실제로 좋은 옵션이 아닙니다. 또한, 내가 방금 달리면

compressor.communicate("Testing") 

위의 두 줄 후에도 여전히 오류와 매달려 있습니다.

  File "/usr/lib/python2.4/subprocess.py", line 1041, in communicate
    rlist, wlist, xlist = select.select(read_set, write_set, [])
도움이 되었습니까?

해결책

문제는 파이프를 여는 순서와 관련이 있다고 생각합니다. Uuencode는 재밌는 일입니다. 올바른 방법으로 들어오는 파이프가 없으면 발사 할 때 윙윙 거리는 것입니다 (Popen 호출에서 파이프로 폭발을 보려면 Stdin과 Stdout로서의 폭발을 보려고합니다).

이 시도:

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(24TL3@4`;2O+"!(`````
`
end

당신이 맞습니다, btw ... 파이프 아래로 일반적인 EOF를 보낼 방법이 없습니다. 결국, 각 프로그램은 실제로 자체 EOF를 정의합니다. 그렇게하는 방법은 파이프를 닫는 것입니다.

편집 : Uuencode에 대해 더 명확해야합니다. 쉘 프로그램으로서 기본 동작은 콘솔 입력을 기대하는 것입니다. "라이브"들어가는 파이프없이 실행하면 콘솔 입력 대기를 차단합니다. 인코더를 두 번째로 열면 컴프레서 파이프 아래로 재료를 보내기 전에 인코더가 타이핑을 시작하기를 기다리고있었습니다. Jerub은 무언가가 차단되었다는 점에서 옳았습니다.

다른 팁

이것은 파이썬에서 직접해야 할 일이 아닙니다. 쉘로이 작업을 수행하는 것이 훨씬 더 나은 아이디어가되는 방식에 관한 편심이 있습니다. subprocess.popen ( "foo | bar", shell = true) 만 사용할 수 있다면 더 좋습니다.

일어날 수있는 일은 GZIP가 아직 모든 입력을 출력 할 수 없었으며, STDOUT 쓰기가 완료 될 때까지 프로세스가 종료되지 않을 것입니다.

Strace를 사용하는 경우 어떤 시스템 호출 프로세스가 차단되는지 볼 수 있습니다. 사용 ps auxwf GZIP 프로세스인지 프로세스를 찾은 다음 사용하십시오. strace -p $pidnum 어떤 시스템이 호출되는지 확인하려면 수행 중입니다. Stdin은 FD 0이고 stdout은 FD 1이며 아마도 해당 파일 설명자에 대한 읽기 또는 쓰기를 볼 수 있습니다.

압축하려고하고 파일 포장지가 필요하지 않은 경우 Zlib 모듈 사용을 고려하십시오.

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

Shell = True 및 Unix Pipes 제안이 작동하지 않는 이유는 무엇입니까?

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()

작동하는 것 같습니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top