以下代码段打开一个gzip文件句柄并向其写入一行,然后在附加模式下再次打开它并将子进程的stdout重定向到gzip文件句柄。
import gzip
import subprocess
with gzip.open("./file.txt.gz", "w") as fh:
fh.write("this is the first line\n")
with gzip.open("./file.txt.gz", "a") as fh:
subprocess.call("echo this is the second line", shell=True, stdout=fh)
当我尝试解压缩文件以查看我写入的内容时,出现以下错误
$ gunzip file.txt.gz
gzip: file.txt.gz: decompression OK, trailing garbage ignored
解压缩的内容仅由第一行
组成$ cat file.txt
this is the first line
当我使用相同的文件句柄来写一行和作为进程的输出时,我得到一个甚至不被gunzip
识别的文件。
import gzip
import subprocess
with gzip.open("./file.txt.gz", "w") as fh:
fh.write("this is the first line\n")
subprocess.call("echo this is the second line", shell=True, stdout=fh)
例如,生成一个不能gunzip
'的文件。
$ gunzip file.txt.gz
gzip: file.txt.gz: not in gzip format
有没有办法将gzip风格的伪文件句柄传递给通过subprocess
运行的进程,或者是否真的没有办法编写非压缩文件,然后返回并压缩它?
答案 0 :(得分:1)
如果你搜索StackOverflow,你会发现这个问题偶尔会出现,但答案并不总是很容易实现。他们的要点似乎是subprocess.call()
无法传递伪文件句柄 - 它必须是真实的东西。标准的解决方法似乎是使用subprocess.Popen()
。
然而,这是我做出的一个简单的妥协:
import gzip
import subprocess
with gzip.open("file.txt.gz", "wt") as handle:
handle.write("this is the first line\n")
completed = subprocess.run("echo 'this is the second line'", shell=True, stdout=subprocess.PIPE, universal_newlines=True)
with gzip.open("file.txt.gz", "at") as handle:
handle.write(completed.stdout)
这个想法是在子进程完成之前延迟附加压缩数据:
> gzcat file.txt.gz
this is the first line
this is the second line
>
在Python 3.5中添加了subprocess.run()
函数