<p>这与Serge Ballesta发布的答案相似,但并不完全相同。使用his进行异步执行,在异步执行中不关心结果。使用mine进行同步处理和结果收集。和他的回答一样,我在这里展示的是Windows解决方案-在Linux中运行bash进程,而不是在Windows中运行cmd。</p>
<pre><code>from subprocess import Popen, PIPE
process = Popen( "cmd.exe", shell=False, universal_newlines=True,
stdin=PIPE, stdout=PIPE, stderr=PIPE )
out, err = process.communicate( commands )
</code></pre>
<p><strong>用法详细信息:</strong>传递给<code>commands</code>方法的<code>process.communicate</code>参数是一个以新行分隔的字符串。例如,如果您只是将批处理文件内容读入字符串,则可以这样运行它,因为它已经有了换行符。</p>
<p><strong>重要信息</strong>:字符串必须以换行结束<code>"\n"</code>。如果不这样做,最后的命令将无法执行。就像您在命令提示符中键入它,但没有在最后按<code>enter</code>。但是,您将在返回的stdout的末尾看到一个神秘的<code>More?</code>行。(这就是你遇到这种情况的原因)。</p>
<p><code>process.communicate</code>按定义同步运行,并返回stdout和stderr消息(如果将它们定向到Popen构造函数中的<code>subprocess.PIPE</code>)。</p>
<p>当您以这种方式创建一个<code>cmd.exe</code>进程并向其传递一个字符串时,结果将与打开命令提示窗口并在其中输入命令完全相同。我是说真的。如果您对此进行测试,您将看到返回的stdout包含您的命令。(如果包含类似于执行批处理文件的<code>@echo off</code>,这并不重要)。</p>
<p>对那些关心“干净”标准输出结果的人的提示:</p>
<ul>
<li><p><code>@echo off</code>不会禁止您的命令出现在此返回的字符串中,但它确实会删除额外的换行符,否则这些换行符会出现在该字符串中。(universal_newlines=True将另一组数据剥离)</p></li>
<li><p>在命令中包含一个<code>@</code>符号前缀允许它们仍然执行。在“正常”批处理过程中,逐行“隐藏”命令。在这种情况下,它是一个安全而简单的标记,通过它可以找到要删除的标准输出行。(如果有人这么倾向的话)</p></li>
<li><p>cmd.exe“header”将出现在您的输出中(显示Windows等的版本)。因为您可能想用<code>@echo off</code>来启动您的命令集,以删除额外的换行符,所以这也是一个找到标题行停止位置和命令/结果开始位置的好方法。</p></li>
</ul>
<p>最后,为了解决“大”输出填充管道并给您带来问题的问题(首先,我认为您需要大量数据返回才能解决问题),这比大多数人在其用例中遇到的问题都要多。其次,如果真的有问题,只需打开一个文件进行写入,并将该文件句柄(对文件对象的引用)传递给stdout/err,而不是<code>PIPE</code>。然后,对创建的文件执行任何所需的操作。</p>