Gzip и стандартный вывод подпроцесса в python - PullRequest
1 голос
/ 18 мая 2010

Я использую python 2.6.4 и обнаружил, что не могу использовать 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

Вот как это выглядит внутри меньше

HI
^_<8B>^H^Hh<C0><F1>K^B<FF>tmp^@^C^@^@^@^@^@^@^@^@^@

, который выглядит так, как будто он вставляется в стандартный вывод в виде текста, а затем помещается в пустой файл gzip. Действительно, если я уберу «Привет \ 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

Что здесь происходит?

UPDATE: Этот предыдущий вопрос задает то же самое: Могу ли я использовать открытый файл gzip с Popen в Python?

Ответы [ 4 ]

7 голосов
/ 18 мая 2010

Нельзя использовать лайки с subprocess, только реальные файлы. Метод fileno() для GzipFile возвращает FD базового файла, так что именно к этому перенаправляется эхо. Затем GzipFile закрывается, записывая пустой файл gzip.

3 голосов
/ 18 мая 2010

просто труба эта присоска

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()
1 голос
/ 18 мая 2010

Я не совсем уверен, почему это не работает (возможно, перенаправление вывода не вызывает запись Python, с чем работает gzip?), Но это работает:

>>> fh.write(subprocess.Popen("echo Hi", shell=True, stdout=subprocess.PIPE).stdout.read())
0 голосов
/ 18 мая 2010

Вам не нужно использовать subprocess для записи в gzip.GzipFile. Вместо этого, пишите в него, как и любой другой файл-подобный объект. Результат автоматически распаковывается!

import gzip
with gzip.open("tmp.gz", "wb") as fh:
    fh.write('echo HI')
...