我试图使用subprocess.Popen
在python中启动程序,stdin
是一些常规文本文件,就像这样。
subprocess.Popen(args, stdout=stdoutFile, stderr=stderrFile, stdin=open(TEXT_FILE))
它工作得很好。但是如果我尝试打开一个gzip压缩文件,我的进程就会失败。
import gzip
subprocess.Popen(args, stdout=stdoutFile, stderr=stderFile, stdin=gzip.open(GZFILE))
我不确定为什么。我的流程认为它没有获得任何数据。
知道为什么吗?难道2不可以互换吗?
答案 0 :(得分:3)
如果传递gzip.open(..)
的返回值,则将其内部文件描述符传递给该文件;从子流程中读取它将返回原始数据,而不是解压缩数据。
您需要将解压缩的数据传递给子流程'标准输入:
subprocess.Popen(args, stdout=stdoutFile, stderr=stderFile,, stdin=subprocess.PIPE)
with gzip.open(GZFILE) as f:
shutil.copyfileobj(f, p.stdin)
# p.stdin.close() # to denote the end of the file.
答案 1 :(得分:1)
就像@falsetru所说,Popen使用原始gzip数据而不是解压缩数据。这是一个完整的例子:
#!/usr/bin/env python3
import gzip
import subprocess
import shutil
filename = 'testfile'
data = 'Hello\n'
# Create some test files
with open(filename, 'w') as f:
f.write(data)
with gzip.open(filename + '.gz', 'wt') as f:
f.write(data)
# Make sure we can read them:
with open(filename) as f:
d = f.read()
print(d == data, d)
with gzip.open(filename + '.gz', 'rt') as f:
d = f.read()
print(d == data, d)
# See what Popen does with the files given as stdin
with open(filename) as f:
result = subprocess.Popen('hexdump -C'.split(), stdin=f,
stdout=subprocess.PIPE)
print(result.stdout.read().decode())
with gzip.open(filename + '.gz') as f:
result = subprocess.Popen('hexdump -C'.split(), stdin=f,
stdout=subprocess.PIPE)
print(result.stdout.read().decode())
# Fix the problem like this...
p = subprocess.Popen('hexdump -C'.split(),
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
with gzip.open(filename + '.gz', 'rb') as f:
with p.stdin:
shutil.copyfileobj(f, p.stdin)
print(p.stdout.read().decode())
# You can use the same pattern for the regular files, too:
p = subprocess.Popen('hexdump -C'.split(),
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
with open(filename, 'rb') as f:
with p.stdin:
shutil.copyfileobj(f, p.stdin)
print(p.stdout.read().decode())
输出:
$ ./subprocess_gzip_stdin.py
True Hello
True Hello
00000000 48 65 6c 6c 6f 0a |Hello.|
00000006
00000000 1f 8b 08 08 fc 30 13 59 02 ff 74 65 73 74 66 69 |.....0.Y..testfi|
00000010 6c 65 00 f3 48 cd c9 c9 e7 02 00 16 35 96 31 06 |le..H.......5.1.|
00000020 00 00 00 |...|
00000023
00000000 48 65 6c 6c 6f 0a |Hello.|
00000006
00000000 48 65 6c 6c 6f 0a |Hello.|
00000006