问题描述
如果我执行以下操作:
导入子流程从 cStringIO 导入 StringIOsubprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=StringIO('one\ntwo\nthree\nfour\nfive\nsix\n')).communicate()[0]
我明白了:
回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 ?文件/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py",第 533 行,在 __init__ 中(p2cread, p2cwrite,文件/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py",第 830 行,在 _get_handles 中p2cread = stdin.fileno()AttributeError: 'cStringIO.StringI' 对象没有属性 'fileno'
显然,cStringIO.StringIO 对象并没有足够接近文件鸭以适应 subprocess.Popen.我该如何解决这个问题?
注意,如果你想发送数据到进程的标准输入,你需要创建 Popen 对象标准输入=管道.同样,要得到任何东西除了结果元组中的 None 之外,你需要给 stdout=PIPE 和/或stderr=PIPE 也是.
替换 os.popen*
pipe = os.popen(cmd, 'w', bufsize)# ==>pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
警告 使用communication() 而不是stdin.write(), stdout.read() 或stderr.read() 避免死锁到任何其他操作系统管道缓冲区填满和阻挡孩子过程.
所以你的例子可以写成如下:
from subprocess import Popen, PIPE, STDOUTp = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)grep_stdout = p.communicate(input=b'one\ntwo\nthree\nfour\nfive\nsix\n')[0]打印(grep_stdout.decode())# ->四# ->五# ->
在 Python 3.5+(encoding
为 3.6+)上,您可以使用 subprocess.run
,将输入作为字符串传递给外部命令并获取其退出状态,并在一次调用中将其输出作为字符串返回:
#!/usr/bin/env python3从子进程导入运行,PIPEp = run(['grep', 'f'], stdout=PIPE,input='one\ntwo\nthree\nfour\n5\nsix\n', encoding='ascii')打印(p.returncode)# ->0打印(p.stdout)# ->四# ->五# ->
If I do the following:
import subprocess
from cStringIO import StringIO
subprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=StringIO('one\ntwo\nthree\nfour\nfive\nsix\n')).communicate()[0]
I get:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py", line 533, in __init__
(p2cread, p2cwrite,
File "/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py", line 830, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'cStringIO.StringI' object has no attribute 'fileno'
Apparently a cStringIO.StringIO object doesn't quack close enough to a file duck to suit subprocess.Popen. How do I work around this?
Popen.communicate()
documentation:
pipe = os.popen(cmd, 'w', bufsize)
# ==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
So your example could be written as follows:
from subprocess import Popen, PIPE, STDOUT
p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'one\ntwo\nthree\nfour\nfive\nsix\n')[0]
print(grep_stdout.decode())
# -> four
# -> five
# ->
On Python 3.5+ (3.6+ for encoding
), you could use subprocess.run
, to pass input as a string to an external command and get its exit status, and its output as a string back in one call:
#!/usr/bin/env python3
from subprocess import run, PIPE
p = run(['grep', 'f'], stdout=PIPE,
input='one\ntwo\nthree\nfour\nfive\nsix\n', encoding='ascii')
print(p.returncode)
# -> 0
print(p.stdout)
# -> four
# -> five
# ->
这篇关于如何将字符串传递到 subprocess.Popen(使用 stdin 参数)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!