Python中的Gzip和子进程的stdout
我正在使用 Python 2.6.4,发现我不能像想象中那样用 subprocess 来处理 gzip。这段代码展示了这个问题:
May 17 18:05:36> python
Python 2.6.4 (r264:75706, Mar 10 2010, 14:41:19)
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import gzip
>>> import subprocess
>>> fh = gzip.open("tmp","wb")
>>> subprocess.Popen("echo HI", shell=True, stdout=fh).wait()
0
>>> fh.close()
>>>
[2]+ Stopped python
May 17 18:17:49> file tmp
tmp: data
May 17 18:17:53> less tmp
"tmp" may be a binary file. See it anyway?
May 17 18:17:58> zcat tmp
zcat: tmp: not in gzip format
这是在 less 里面的样子
HI
^_<8B>^H^Hh<C0><F1>K^B<FF>tmp^@^C^@^@^@^@^@^@^@^@^@
看起来它把内容当作文本放进了标准输出,然后又放了一个空的 gzip 文件。实际上,如果我去掉 "Hi\n",那么结果就变成这样:
May 17 18:22:34> file tmp
tmp: gzip compressed data, was "tmp", last modified: Mon May 17 18:17:12 2010, max compression
这到底是怎么回事呢?
更新:之前有个问题也是在问同样的事情:我可以在 Python 中用 Popen 使用已打开的 gzip 文件吗?
4 个回答
1
我不太确定为什么这个不管用(可能是因为输出重定向没有调用到python的写入功能,而gzip是依赖这个的?)不过这个方法是有效的:
>>> fh.write(subprocess.Popen("echo Hi", shell=True, stdout=subprocess.PIPE).stdout.read())
8
就把那个东西直接连接起来就行了。
from subprocess import Popen,PIPE
GZ = Popen("gzip > outfile.gz",stdin=PIPE,shell=True)
P = Popen("echo HI",stdout=GZ.stdin,shell=True)
# these next three must be in order
P.wait()
GZ.stdin.close()
GZ.wait()
10
你不能用类似文件的东西来配合 subprocess
,只能用真正的文件。GzipFile
的 fileno()
方法会返回底层文件的文件描述符,所以这就是 echo 重定向到的地方。然后,GzipFile 会关闭,结果就写了一个空的 gzip 文件。