2

gzip、uuencode、標準出力に出力したいデータがあります。私が基本的に持っているものは次のとおりです。

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

コンプレッサにデータを供給する方法は、compressor.stdin.write(stuff) を使用することです。

私が本当にする必要があるのは、EOF をコンプレッサーに送信することですが、その方法がわかりません。

ある時点で、compressor.stdin.close() を試しましたが、うまくいきません。圧縮プログラムがファイルに直接書き込む場合はうまく機能しますが、上記の場合、プロセスは終了せず、圧縮プログラムで停止します。待つ()。

提案?この場合、gzip は一例であり、あるプロセスの出力を別のプロセスにパイプする必要があります。

注: 圧縮する必要があるデータはメモリに収まらないため、ここでは通信は適切なオプションではありません。また、私がただ走ると

compressor.communicate("Testing") 

上記の2行の後、それでもエラーでハングします

  ファイル「/usr/lib/python2.4/subprocess.py」、1041行目、通信中
    rlist、wlist、xlist = select.select(read_set、write_set、[])
4

3 に答える 3

4

問題は、パイプを開く順序にある​​と思われます。UUEncode の面白い点は、適切な方法で着信パイプがない場合に起動すると泣き言を言うことです (標準入力と標準出力として PIPE だけで爆発を確認するために、Popen 呼び出しでくそったれを単独で起動してみてください)。

これを試して:

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

そうです、ところで...一般的なEOFをパイプに送信する方法はありません。結局のところ、各プログラムは実際には独自の EOF を定義しています。あなたがやろうとしていたように、それを行う方法はパイプを閉じることです。

編集:uuencodeについてもっと明確にする必要があります。シェル プログラムとしてのデフォルトの動作は、コンソール入力を期待することです。「ライブ」の着信パイプなしで実行すると、コンソール入力の待機がブロックされます。エンコーダーを 2 番目に開くと、コンプレッサー パイプに材料を送る前に、エンコーダーは入力を開始するのを待ってブロックしていました。何かが邪魔をしているという点で、Jerub は正しかった。

于 2009-03-06T01:37:43.090 に答える
3

これは、Python で直接行うべきものではありません。シェルでこれを行う方がはるかに優れた方法であるという風変わりな作業があります。subprocess.Popen("foo | bar", shell=True) を使用できる場合は、なおさらです。

gzip がすべての入力をまだ出力できておらず、stdout への書き込みが完了するまでプロセスが終了しない可能性があります。

strace を使用すると、プロセスがブロックしているシステム コールを確認できます。ps auxwfgzip プロセスであるプロセスを検出するために使用し、strace -p $pidnum実行しているシステム コールを確認するために使用します。stdin は FD 0 であり、stdout は FD 1 であることに注意してください。おそらく、これらのファイル記述子で読み取りまたは書き込みを行うことがわかります。

于 2009-03-06T00:49:17.887 に答える
1

圧縮したいだけでファイルラッパーが必要ない場合は、 zlib モジュールの使用を検討してください

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

shell=True と unix パイプの提案が機能しない理由は何ですか?

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

動作するようです

于 2009-03-06T00:34:00.420 に答える