要澄清一些要点:
正如jro所提到的,正确的方法是使用subprocess.communicate
。
但是,在stdin
使用subprocess.communicate
时input
,您需要stdin=subprocess.PIPE
根据docs启动子过程。
请注意,如果要将数据发送到进程的stdin,则需要使用stdin = PIPE创建Popen对象。同样,要在结果元组中获得除None以外的任何内容,您还需要提供stdout = PIPE和/或stderr = PIPE。
此外QED在使用Python 3.4,您需要将字符串编码的评论所说,这意味着你需要字节传递给input
,而不是一个string
。这并非完全正确。根据文档,如果流以文本模式打开,则输入应为字符串(源是同一页)。
如果以文本模式打开流,则输入必须为字符串。否则,它必须是字节。
因此,如果未在文本模式下显式打开流,则应执行以下操作:
import subprocess
command = ['myapp', '--arg1', 'value_for_arg1']
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.communicate(input='some data'.encode())[0]
我特意将stderr
上面的值STDOUT
作为示例。
话虽这么说,有时您可能想要另一个进程的输出,而不是从头开始构建它。假设您要运行的等效项echo -n 'CATCH\nme' | grep -i catch | wc -m
。通常,这应该返回“ CATCH”中的数字字符以及换行符,结果为6。此处的回显点是将CATCH\nme
数据馈送到grep。因此,我们可以使用Python子wc
进程链中的stdin作为变量将数据提供给grep,然后将stdout作为PIPE传递给进程的stdin(同时,摆脱多余的换行符):
import subprocess
what_to_catch = 'catch'
what_to_feed = 'CATCH\nme'
p1 = subprocess.Popen(['grep', '-i', what_to_catch], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p1_out = p1.communicate(input=what_to_feed.encode())[0]
p1_out = p1_out.decode().strip().encode()
p2 = subprocess.Popen(['wc', '-m'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = p2.communicate(input=p1_out)[0].decode().strip()
这与此处的响应有些不同,在此处您直接通过管道传输两个进程,而无需直接在Python中添加数据。
希望可以帮助某人。
input
的subprocess.run
; 例如,subprocess.run(['cat'], input='foobar'.encode('utf-8'))