<p>要将所有stdout作为字符串获取:</p>
<pre><code>from subprocess import check_output as qx
cmd = r'C:\Tools\Dvb_pid_3_0.exe'
output = qx(cmd)
</code></pre>
<p>要将stdout和stderr同时作为单个字符串:</p>
<pre><code>from subprocess import STDOUT
output = qx(cmd, stderr=STDOUT)
</code></pre>
<p>要将所有行作为列表:</p>
<pre><code>lines = output.splitlines()
</code></pre>
<p>要获取子流程打印的行,请执行以下操作:</p>
<pre><code>from subprocess import Popen, PIPE
p = Popen(cmd, stdout=PIPE, bufsize=1)
for line in iter(p.stdout.readline, ''):
print line,
p.stdout.close()
if p.wait() != 0:
raise RuntimeError("%r failed, exit status: %d" % (cmd, p.returncode))
</code></pre>
<p>将<code>stderr=STDOUT</code>添加到<code>Popen()</code>调用以合并stdout/stderr。</p>
<p>注意:如果<code>cmd</code>在非交互模式下使用块缓冲,则在缓冲区刷新之前不会显示行。<a href="https://bitbucket.org/geertj/winpexpect/wiki/Home" rel="noreferrer">^{<cd4>}</a>模块可能能够更快地获得输出。</p>
<p>要将输出保存到文件:</p>
<pre><code>import subprocess
with open('output.txt', 'wb') as f:
subprocess.check_call(cmd, stdout=f)
# to read line by line
with open('output.txt') as f:
for line in f:
print line,
</code></pre>
<p>如果<code>cmd</code>始终需要输入,即使是空输入;请设置<code>stdin</code>:</p>
<pre><code>import os
with open(os.devnull, 'rb') as DEVNULL:
output = qx(cmd, stdin=DEVNULL) # use subprocess.DEVNULL on Python 3.3+
</code></pre>
<p>您可以组合这些解决方案,例如合并stdout/stderr,将输出保存到文件中,并提供空输入:</p>
<pre><code>import os
from subprocess import STDOUT, check_call as x
with open(os.devnull, 'rb') as DEVNULL, open('output.txt', 'wb') as f:
x(cmd, stdin=DEVNULL, stdout=f, stderr=STDOUT)
</code></pre>
<p>要将所有输入作为单个字符串提供,可以使用<code>.communicate()</code>方法:</p>
<pre><code>#!/usr/bin/env python
from subprocess import Popen, PIPE
cmd = ["python", "test.py"]
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
stdout_text, stderr_text = p.communicate(input="1\n\n")
print("stdout: %r\nstderr: %r" % (stdout_text, stderr_text))
if p.returncode != 0:
raise RuntimeError("%r failed, status code %d" % (cmd, p.returncode))
</code></pre>
<p>其中<code>test.py</code>:</p>
<pre><code>print raw_input('abc')[::-1]
raw_input('press enter to exit')
</code></pre>
<p>如果您与程序的交互更像是一个对话,而不是您可能需要的<a href="https://bitbucket.org/geertj/winpexpect/wiki/Home" rel="noreferrer">^{<cd4>} module</a>。这是一张<a href="http://www.noah.org/wiki/Pexpect#Overview" rel="noreferrer">example from ^{<cd10>} docs</a>:</p>
<pre><code># This connects to the openbsd ftp site and
# downloads the recursive directory listing.
from winpexpect import winspawn as spawn
child = spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('cd pub')
child.expect('ftp> ')
child.sendline ('get ls-lR.gz')
child.expect('ftp> ')
child.sendline ('bye')
</code></pre>
<p>要在Windows上发送诸如<code>F3</code>,<code>F10</code>之类的特殊键,您可能需要<a href="http://www.rutherfurd.net/python/sendkeys/" rel="noreferrer">^{<cd13>} module</a>或其纯Python实现<a href="http://code.google.com/p/sendkeys-ctypes/" rel="noreferrer">^{<cd14>}</a>。类似于:</p>
<pre><code>from SendKeys import SendKeys
SendKeys(r"""
{LWIN}
{PAUSE .25}
r
C:\Tools\Dvb_pid_3_0.exe{ENTER}
{PAUSE 1}
1{ENTER}
{PAUSE 1}
2{ENTER}
{PAUSE 1}
{F3}
{PAUSE 1}
{F10}
""")
</code></pre>
<p>它不捕获输出。</p>