如何将一个字符串传递给subprocess.Popen(使用stdin参数)?

345

如果我执行以下操作:

import subprocess
from cStringIO import StringIO
subprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=StringIO('one\ntwo\nthree\nfour\nfive\nsix\n')).communicate()[0]

我得到:

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'

显然,cStringIO.StringIO对象在关闭方面与文件对象不够相似,无法满足subprocess.Popen的要求。我该如何解决这个问题?


3
与其因为这个被删除而争论我的答案,我将它作为评论添加上去……建议阅读:Doug Hellmann的Python模块每周博客文章——子进程 - Daryl Spitzer
4
这篇博客文章存在多个错误,例如:第一个代码示例:call(['ls', '-1'], shell=True) 是错误的。我建议阅读subprocess标签描述中的常见问题。特别是为什么使用参数为序列时,subprocess.Popen不起作用? 解释了为什么 call(['ls', '-1'], shell=True) 是错误的。我记得在博客文章下留过评论,但出于某种原因现在找不到它们了。 - jfs
2
请参考较新的subprocess.run,网址为https://dev59.com/MFYM5IYBdhLWcg3wgwXH#59496029 - user3064538
12个回答

3

对于grep来说,这有点过头了,但是在我的探索过程中,我学到了Linux命令expect和Python库pexpect

  • expect:用于与交互式程序进行对话
  • pexpect:Python模块,可生成子应用程序并控制它们,并响应其输出中预期的模式。
import pexpect
child = pexpect.spawn('grep f', timeout=10)
child.sendline('text to match')
print(child.before)

使用像 ftp 这样的交互式 shell 应用程序非常简单,使用pexpect

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

2
p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)    
p.stdin.write('one\n')
time.sleep(0.5)
p.stdin.write('two\n')
time.sleep(0.5)
p.stdin.write('three\n')
time.sleep(0.5)
testresult = p.communicate()[0]
time.sleep(0.5)
print(testresult)

NameError: 全局名称 'PIPE' 未定义 - Hayden Thring

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接