mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 06:55:36 +08:00
133 lines
128 KiB
HTML
133 lines
128 KiB
HTML
<div class="body" role="main"><div class="section" id="module-subprocess"><h1><span class="yiyi-st" id="yiyi-10">17.5. <a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a> —— 子进程管理</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/subprocess.py">Lib/subprocess.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块允许你生成新进程,连接到其输入/输出/错误管道,并获取其返回码。</span><span class="yiyi-st" id="yiyi-13">此模块旨在替换多个旧的模块和函数:</span></p><pre><code class="language-python"><span></span><span class="n">os</span><span class="o">.</span><span class="n">system</span>
|
||
<span class="n">os</span><span class="o">.</span><span class="n">spawn</span><span class="o">*</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-14">有关如何使用<a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块来替换这些模块和函数,请参见以下部分。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-15">另可参阅</span></p><p class="last"><span class="yiyi-st" id="yiyi-16"><span class="target" id="index-0"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0324"><strong>PEP 324</strong></a> —— 提议subprocess模块的PEP</span></p></div><div class="section" id="using-the-subprocess-module"><h2><span class="yiyi-st" id="yiyi-17">17.5.1. </span><span class="yiyi-st" id="yiyi-18">使用<a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块</span></h2><p><span class="yiyi-st" id="yiyi-19">调用subprocess的推荐方法是对于它可以处理的所有使用场景都使用<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>函数。</span><span class="yiyi-st" id="yiyi-20">对于更高级的使用场景,可以直接使用底层的<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>接口。</span></p><p><span class="yiyi-st" id="yiyi-21"><a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>函数是在Python 3.5中添加的;如果你需要保留与旧版本的兼容性,请参阅<a class="reference internal" href="#call-function-trio"><span>旧版高级API</span></a>部分。</span></p><dl class="function"><dt id="subprocess.run"><span class="yiyi-st" id="yiyi-22"> <code class="descclassname">subprocess.</code><code class="descname">run</code><span class="sig-paren">(</span><em>args</em>, <em>*</em>, <em>stdin=None</em>, <em>input=None</em>, <em>stdout=None</em>, <em>stderr=None</em>, <em>shell=False</em>, <em>timeout=None</em>, <em>check=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-23">运行<em>args</em>描述的命令。</span><span class="yiyi-st" id="yiyi-24">等待命令完成,然后返回一个<a class="reference internal" href="#subprocess.CompletedProcess" title="subprocess.CompletedProcess"><code class="xref py py-class docutils literal"><span class="pre">CompletedProcess</span></code></a>实例。</span></p><p><span class="yiyi-st" id="yiyi-25">上面显示的参数只是最常见的参数,在下面的<a class="reference internal" href="#frequently-used-arguments"><span>常用参数</span></a>中描述(因此在这个简写形式中使用keyword-only写法)。</span><span class="yiyi-st" id="yiyi-26">完整的函数形式很大程度上与<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>构造函数相同 —— 除<em>timeout</em>、<em>input</em>和<em>check</em>之外,该函数的所有参数都传递给Popen接口。</span></p><p><span class="yiyi-st" id="yiyi-27">默认情况下,它不捕获标准输出或标准错误。</span><span class="yiyi-st" id="yiyi-28">如果要这样做,请为<em>stdout</em>和/或<em>stderr</em>参数传递<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-29"><em>timeout</em>参数被传递给<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>。</span><span class="yiyi-st" id="yiyi-30">如果timeout超时,子进程将被终止并等待。</span><span class="yiyi-st" id="yiyi-31">子进程终止后,将重新引发<a class="reference internal" href="#subprocess.TimeoutExpired" title="subprocess.TimeoutExpired"><code class="xref py py-exc docutils literal"><span class="pre">TimeoutExpired</span></code></a>异常。</span></p><p><span class="yiyi-st" id="yiyi-32"><em>input</em>参数传递给<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>,因此传递到子进程的标准输入。</span><span class="yiyi-st" id="yiyi-33">如果使用,它必须是字节序列,或者如果<code class="docutils literal"><span class="pre">universal_newlines=True</span></code>,则为字符串。</span><span class="yiyi-st" id="yiyi-34">用到时,会自动以<code class="docutils literal"><span class="pre">stdin=PIPE</span></code>创建内部的<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>对象,也可能用不到<em>stdin</em>参数。</span></p><p><span class="yiyi-st" id="yiyi-35">如果<em>check</em>为True,并且进程以非零退出码退出,则会引发<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>异常。</span><span class="yiyi-st" id="yiyi-36">该异常的属性中保存有参数、 退出码和标准输出及标准错误(如果它们被捕捉到)。</span></p><p><span class="yiyi-st" id="yiyi-37">例子:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">"ls"</span><span class="p">,</span> <span class="s2">"-l"</span><span class="p">])</span> <span class="c1"># doesn't capture output</span>
|
||
<span class="go">CompletedProcess(args=['ls', '-l'], returncode=0)</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"exit 1"</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
<span class="c">...</span>
|
||
<span class="gr">subprocess.CalledProcessError</span>: <span class="n">Command 'exit 1' returned non-zero exit status 1</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">"ls"</span><span class="p">,</span> <span class="s2">"-l"</span><span class="p">,</span> <span class="s2">"/dev/null"</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
|
||
<span class="go">CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,</span>
|
||
<span class="go">stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-38"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div></dd></dl><dl class="class"><dt id="subprocess.CompletedProcess"><span class="yiyi-st" id="yiyi-39"> <em class="property">class </em><code class="descclassname">subprocess.</code><code class="descname">CompletedProcess</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-40">从<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>返回的值,表示已完成的进程。</span></p><dl class="attribute"><dt id="subprocess.CompletedProcess.args"><span class="yiyi-st" id="yiyi-41"> <code class="descname">args</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-42">用于启动进程的参数。</span><span class="yiyi-st" id="yiyi-43">这可能是一个列表或字符串。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CompletedProcess.returncode"><span class="yiyi-st" id="yiyi-44"> <code class="descname">returncode</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-45">子进程的退出状态。</span><span class="yiyi-st" id="yiyi-46">通常,退出状态为0表示它已成功运行。</span></p><p><span class="yiyi-st" id="yiyi-47">负值<code class="docutils literal"><span class="pre">-N</span></code>表示子进程被信号<code class="docutils literal"><span class="pre">N</span></code>终止(仅POSIX)。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CompletedProcess.stdout"><span class="yiyi-st" id="yiyi-48"> <code class="descname">stdout</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-49">从子进程中捕获的标准输出。</span><span class="yiyi-st" id="yiyi-50">一个字节序列,如果<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>用<code class="docutils literal"><span class="pre">universal_newlines=True</span></code>调用则为一个字符串。</span><span class="yiyi-st" id="yiyi-51">如果没有捕获标准输出,则为None。</span></p><p><span class="yiyi-st" id="yiyi-52">如果使用<code class="docutils literal"><span class="pre">stderr=subprocess.STDOUT</span></code>运行进程,stdout和stderr将在此属性中合并,<a class="reference internal" href="#subprocess.CompletedProcess.stderr" title="subprocess.CompletedProcess.stderr"><code class="xref py py-attr docutils literal"><span class="pre">stderr</span></code></a>将为None。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CompletedProcess.stderr"><span class="yiyi-st" id="yiyi-53"> <code class="descname">stderr</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-54">从子进程中捕获的标准错误。</span><span class="yiyi-st" id="yiyi-55">一个字节序列,如果<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>用<code class="docutils literal"><span class="pre">universal_newlines=True</span></code>调用则为一个字符串。</span><span class="yiyi-st" id="yiyi-56">如果没有捕获标准错误,则为None。</span></p></dd></dl><dl class="method"><dt id="subprocess.CompletedProcess.check_returncode"><span class="yiyi-st" id="yiyi-57"> <code class="descname">check_returncode</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-58">如果<a class="reference internal" href="#subprocess.CompletedProcess.returncode" title="subprocess.CompletedProcess.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>不为零,则引发<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>。</span></p></dd></dl><div class="versionadded"><p><span class="yiyi-st" id="yiyi-59"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="subprocess.DEVNULL"><span class="yiyi-st" id="yiyi-60"> <code class="descclassname">subprocess.</code><code class="descname">DEVNULL</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-61">可用作<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>的<em>stdin</em>、<em>stdout</em>或<em>stderr</em>参数的特殊值,指示将使用<a class="reference internal" href="os.html#os.devnull" title="os.devnull"><code class="xref py py-data docutils literal"><span class="pre">os.devnull</span></code></a>这个特殊文件。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-62"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="subprocess.PIPE"><span class="yiyi-st" id="yiyi-63"> <code class="descclassname">subprocess.</code><code class="descname">PIPE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-64">可用作<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>的<em>stdin</em>、<em>stdout</em>或<em>stderr</em>参数的特殊值,表示应打开相应标准流的管道。</span><span class="yiyi-st" id="yiyi-65">主要用于<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>。</span></p></dd></dl><dl class="data"><dt id="subprocess.STDOUT"><span class="yiyi-st" id="yiyi-66"> <code class="descclassname">subprocess.</code><code class="descname">STDOUT</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-67">可用作<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>的<em>stderr</em>参数的特殊值,表示标准错误应与标准输出放在同一句柄中。</span></p></dd></dl><dl class="exception"><dt id="subprocess.SubprocessError"><span class="yiyi-st" id="yiyi-68"> <em class="property">exception </em><code class="descclassname">subprocess.</code><code class="descname">SubprocessError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-69">此模块中所有其他异常的基类。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-70"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="exception"><dt id="subprocess.TimeoutExpired"><span class="yiyi-st" id="yiyi-71"> <em class="property">exception </em><code class="descclassname">subprocess.</code><code class="descname">TimeoutExpired</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-72"><a class="reference internal" href="#subprocess.SubprocessError" title="subprocess.SubprocessError"><code class="xref py py-exc docutils literal"><span class="pre">SubprocessError</span></code></a>的子类,当等待子进程的timeout超时时引发。</span></p><dl class="attribute"><dt id="subprocess.TimeoutExpired.cmd"><span class="yiyi-st" id="yiyi-73"> <code class="descname">cmd</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-74">用于产生子进程的命令。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.TimeoutExpired.timeout"><span class="yiyi-st" id="yiyi-75"> <code class="descname">timeout</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-76">超时(以秒为单位)。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.TimeoutExpired.output"><span class="yiyi-st" id="yiyi-77"> <code class="descname">output</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-78">子进程的输出(如果它由<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>或<a class="reference internal" href="#subprocess.check_output" title="subprocess.check_output"><code class="xref py py-func docutils literal"><span class="pre">check_output()</span></code></a>捕获)。</span><span class="yiyi-st" id="yiyi-79">否则,为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.TimeoutExpired.stdout"><span class="yiyi-st" id="yiyi-80"> <code class="descname">stdout</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-81">用于输出的别名,为了与<a class="reference internal" href="#subprocess.TimeoutExpired.stderr" title="subprocess.TimeoutExpired.stderr"><code class="xref py py-attr docutils literal"><span class="pre">stderr</span></code></a>对称。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.TimeoutExpired.stderr"><span class="yiyi-st" id="yiyi-82"> <code class="descname">stderr</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-83">子进程的标准错误输出(如果它由<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>捕获)。</span><span class="yiyi-st" id="yiyi-84">否则,为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><div class="versionadded"><p><span class="yiyi-st" id="yiyi-85"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-86"><span class="versionmodified">在版本3.5中的更改:</span>添加<em>stdout</em>和<em>stderr</em>属性</span></p></div></dd></dl><dl class="exception"><dt id="subprocess.CalledProcessError"><span class="yiyi-st" id="yiyi-87"> <em class="property">exception </em><code class="descclassname">subprocess.</code><code class="descname">CalledProcessError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-88"><a class="reference internal" href="#subprocess.SubprocessError" title="subprocess.SubprocessError"><code class="xref py py-exc docutils literal"><span class="pre">SubprocessError</span></code></a>子类,当<a class="reference internal" href="#subprocess.check_call" title="subprocess.check_call"><code class="xref py py-func docutils literal"><span class="pre">check_call()</span></code></a>或<a class="reference internal" href="#subprocess.check_output" title="subprocess.check_output"><code class="xref py py-func docutils literal"><span class="pre">check_output()</span></code></a>运行的进程返回非零退出状态时引发。</span></p><dl class="attribute"><dt id="subprocess.CalledProcessError.returncode"><span class="yiyi-st" id="yiyi-89"> <code class="descname">returncode</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-90">子进程的退出状态。</span><span class="yiyi-st" id="yiyi-91">如果进程由于信号而退出,则它将是负的信号数。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CalledProcessError.cmd"><span class="yiyi-st" id="yiyi-92"> <code class="descname">cmd</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-93">用于产生子进程的命令。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CalledProcessError.output"><span class="yiyi-st" id="yiyi-94"> <code class="descname">output</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-95">子进程的输出(如果它由<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>或<a class="reference internal" href="#subprocess.check_output" title="subprocess.check_output"><code class="xref py py-func docutils literal"><span class="pre">check_output()</span></code></a>捕获)。</span><span class="yiyi-st" id="yiyi-96">否则,为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CalledProcessError.stdout"><span class="yiyi-st" id="yiyi-97"> <code class="descname">stdout</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-98">用于输出的别名,为了与<a class="reference internal" href="#subprocess.CalledProcessError.stderr" title="subprocess.CalledProcessError.stderr"><code class="xref py py-attr docutils literal"><span class="pre">stderr</span></code></a>对称。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.CalledProcessError.stderr"><span class="yiyi-st" id="yiyi-99"> <code class="descname">stderr</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-100">子进程的标准错误输出(如果它由<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>捕获)。</span><span class="yiyi-st" id="yiyi-101">否则,为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-102"><span class="versionmodified">在版本3.5中的更改:</span>添加<em>stdout</em>和<em>stderr</em>属性</span></p></div></dd></dl><div class="section" id="frequently-used-arguments"><h3><span class="yiyi-st" id="yiyi-103">17.5.1.1. </span><span class="yiyi-st" id="yiyi-104">常用参数</span></h3><p><span class="yiyi-st" id="yiyi-105">为了支持各种各样的场景,<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>构造函数(和其便利函数)接受大量的可选参数。</span><span class="yiyi-st" id="yiyi-106">对于大部分典型的使用场景,这些参数中的许多个可以安全地保持为默认值。</span><span class="yiyi-st" id="yiyi-107">最常用到的参数有:</span></p>
|
||
<blockquote> <div>
|
||
<p><span class="yiyi-st" id="yiyi-510"><em>args</em>是所有调用所必需的,应该为一个字符串或一个程序参数序列。</span><span class="yiyi-st" id="yiyi-511">通常倾向提供参数序列,因为它允许这个模块来处理任何所需的转义和引用参数(例如,允许文件名中的空格)。</span><span class="yiyi-st" id="yiyi-512">如果传递单个字符串,<em>shell</em>必须为<a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>(见下文),否则字符串必须简单地命名要执行的程序而不指定任何参数。</span></p>
|
||
<p><span class="yiyi-st" id="yiyi-513"><em>stdin</em>、<em>stdout</em>和<em>stderr</em>分别指定执行程序的标准输入,标准输出和标准错误文件句柄。</span><span class="yiyi-st" id="yiyi-514">有效值有<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>、<a class="reference internal" href="#subprocess.DEVNULL" title="subprocess.DEVNULL"><code class="xref py py-data docutils literal"><span class="pre">DEVNULL</span></code></a>,一个存在的文件描述器(正整数),一个存在的文件对象和<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-515"><a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>表示应该为子进程创建新的管道。</span><span class="yiyi-st" id="yiyi-516"><a class="reference internal" href="#subprocess.DEVNULL" title="subprocess.DEVNULL"><code class="xref py py-data docutils literal"><span class="pre">DEVNULL</span></code></a>表示将使用特殊文件<a class="reference internal" href="os.html#os.devnull" title="os.devnull"><code class="xref py py-data docutils literal"><span class="pre">os.devnull</span></code></a>。</span><span class="yiyi-st" id="yiyi-517">使用默认设置<code class="docutils literal"><span class="pre">None</span></code>,则不会发生重定向;子进程的文件句柄将从父进程继承。</span><span class="yiyi-st" id="yiyi-518">此外,<em>stderr</em>可以是<a class="reference internal" href="#subprocess.STDOUT" title="subprocess.STDOUT"><code class="xref py py-data docutils literal"><span class="pre">STDOUT</span></code></a>,表示来自子进程的标准错误数据应该捕获到与<em>stdout</em>相同的文件句柄中。</span></p>
|
||
<p id="index-1"><span class="yiyi-st" id="yiyi-519">如果<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">False</span></code>,则文件对象<em>stdin</em>、<em>stdout</em>和<em>stderr</em>将以二进制流打开,并且不对行结束进行转换。</span></p>
|
||
<p><span class="yiyi-st" id="yiyi-520">如果<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">True</span></code>,则这些文件对象将使用<a class="reference internal" href="locale.html#locale.getpreferredencoding" title="locale.getpreferredencoding"><code class="xref py py-func docutils literal"><span class="pre">locale.getpreferredencoding(False)</span></code></a>返回的编码以<a class="reference internal" href="../glossary.html#term-universal-newlines"><span class="xref std std-term">通用换行符</span></a>格式的文本流打开。</span><span class="yiyi-st" id="yiyi-521">对于<em>stdin</em>,输入中的行结束字符<code class="docutils literal"><span class="pre">'\n'</span></code>将转换为默认行分隔符<a class="reference internal" href="os.html#os.linesep" title="os.linesep"><code class="xref py py-data docutils literal"><span class="pre">os.linesep</span></code></a>。</span><span class="yiyi-st" id="yiyi-522">对于<em>stdout</em>和<em>stderr</em>,输出中的所有行结尾将转换为<code class="docutils literal"><span class="pre">'\n'</span></code>。</span><span class="yiyi-st" id="yiyi-523">有关详细信息,请参阅<a class="reference internal" href="io.html#io.TextIOWrapper" title="io.TextIOWrapper"><code class="xref py py-class docutils literal"><span class="pre">io.TextIOWrapper</span></code></a>类的文档中其构造函数的<em>newline</em>参数为<code class="docutils literal"><span class="pre">None</span></code>的时候。</span></p>
|
||
<div class="admonition note">
|
||
<p class="first admonition-title"><span class="yiyi-st" id="yiyi-524">注意</span></p>
|
||
<p class="last"><span class="yiyi-st" id="yiyi-525">文件对象<a class="reference internal" href="#subprocess.Popen.stdin" title="subprocess.Popen.stdin"><code class="xref py py-attr docutils literal"><span class="pre">Popen.stdin</span></code></a>、<a class="reference internal" href="#subprocess.Popen.stdout" title="subprocess.Popen.stdout"><code class="xref py py-attr docutils literal"><span class="pre">Popen.stdout</span></code></a>和<a class="reference internal" href="#subprocess.Popen.stderr" title="subprocess.Popen.stderr"><code class="xref py py-attr docutils literal"><span class="pre">Popen.stderr</span></code></a>的新行属性不会由<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>方法更新。</span></p> </div>
|
||
<p><span class="yiyi-st" id="yiyi-526">如果<em>shell</em>是<code class="docutils literal"><span class="pre">True</span></code>,则将通过shell执行指定的命令。</span><span class="yiyi-st" id="yiyi-527">如果你使用Python主要是由于它能提供大多数系统shell不能提供的增强的控制流,并且仍然希望方便地访问其他shell功能,如shell管道、文件名通配符、环境变量扩展和扩展<code class="docutils literal"><span class="pre">〜</span></code>到用户的主目录,这会很有用。</span><span class="yiyi-st" id="yiyi-528">但是请注意,Python本身提供许多类shell特性的实现(特别是<a class="reference internal" href="glob.html#module-glob" title="glob: Unix shell style pathname pattern expansion."><code class="xref py py-mod docutils literal"><span class="pre">glob</span></code></a>、<a class="reference internal" href="fnmatch.html#module-fnmatch" title="fnmatch: Unix shell style filename pattern matching."><code class="xref py py-mod docutils literal"><span class="pre">fnmatch</span></code></a>、<a class="reference internal" href="os.html#os.walk" title="os.walk"><code class="xref py py-func docutils literal"><span class="pre">os.walk()</span></code></a>、<a class="reference internal" href="os.path.html#os.path.expandvars" title="os.path.expandvars"><code class="xref py py-func docutils literal"><span class="pre">os.path.expandvars()</span></code></a>、<a class="reference internal" href="os.path.html#os.path.expanduser" title="os.path.expanduser"><code class="xref py py-func docutils literal"><span class="pre">os.path.expanduser()</span></code></a>和<a class="reference internal" href="shutil.html#module-shutil" title="shutil: High-level file operations, including copying."><code class="xref py py-mod docutils literal"><span class="pre">shutil</span></code></a>)。</span></p>
|
||
<div class="versionchanged">
|
||
<p><span class="yiyi-st" id="yiyi-529"><span class="versionmodified">版本3.3中的变化:</span>当<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">True</span></code>时,类使用<a class="reference internal" href="locale.html#locale.getpreferredencoding" title="locale.getpreferredencoding"><code class="xref py py-func docutils literal"><span class="pre">locale.getpreferredencoding(False)</span></code></a>而不是<code class="docutils literal"><span class="pre">locale.getpreferredencoding()</span></code>的编码。</span><span class="yiyi-st" id="yiyi-530">有关此更改的详细信息,请参阅<a class="reference internal" href="io.html#io.TextIOWrapper" title="io.TextIOWrapper"><code class="xref py py-class docutils literal"><span class="pre">io.TextIOWrapper</span></code></a>类。</span></p> </div> <div class="admonition note">
|
||
<p class="first admonition-title"><span class="yiyi-st" id="yiyi-531">注意</span></p> <p class="last"><span class="yiyi-st" id="yiyi-532">在使用<code class="docutils literal"><span class="pre">shell=True</span></code>之前,请先阅读<a class="reference internal" href="#security-considerations">安全注意事项</a>部分。</span></p> </div> </div></blockquote>
|
||
<p><span class="yiyi-st" id="yiyi-108">这些选项以及所有其他选项在<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>构造函数文档中有更详细的描述。</span></p></div><div class="section" id="popen-constructor"><h3><span class="yiyi-st" id="yiyi-110">17.5.1.2. </span><span class="yiyi-st" id="yiyi-111">Popen构造函数</span></h3><p><span class="yiyi-st" id="yiyi-112">此模块中,底层的进程创建和管理由<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>类处理。</span><span class="yiyi-st" id="yiyi-113">它提供很多灵活性,以便开发人员能够处理便利函数未涵盖的较不常见的情况。</span></p><dl class="class"><dt id="subprocess.Popen"><span class="yiyi-st" id="yiyi-114"> <em class="property">class </em><code class="descclassname">subprocess.</code><code class="descname">Popen</code><span class="sig-paren">(</span><em>args</em>, <em>bufsize=-1</em>, <em>executable=None</em>, <em>stdin=None</em>, <em>stdout=None</em>, <em>stderr=None</em>, <em>preexec_fn=None</em>, <em>close_fds=True</em>, <em>shell=False</em>, <em>cwd=None</em>, <em>env=None</em>, <em>universal_newlines=False</em>, <em>startupinfo=None</em>, <em>creationflags=0</em>, <em>restore_signals=True</em>, <em>start_new_session=False</em>, <em>pass_fds=()</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-115">在新的进程中执行子程序。</span><span class="yiyi-st" id="yiyi-116">在POSIX上,该类使用类似<a class="reference internal" href="os.html#os.execvp" title="os.execvp"><code class="xref py py-meth docutils literal"><span class="pre">os.execvp()</span></code></a>的行为来执行子程序。</span><span class="yiyi-st" id="yiyi-117">在Windows上,该类使用Windows的<code class="docutils literal"><span class="pre">CreateProcess()</span></code>函数。</span><span class="yiyi-st" id="yiyi-118"><a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>的参数如下。</span></p><p><span class="yiyi-st" id="yiyi-119"><em>args</em> 应该是一个程序参数的序列或者一个单一的字符串。</span><span class="yiyi-st" id="yiyi-120">默认情况下,如果<em>args</em> 是一个序列,那么执行的程序是<em>args</em> 的第一个元素。</span><span class="yiyi-st" id="yiyi-121">如果<em>args</em> 是一个字符串,那么其解释将与平台无关并在下文有描述。</span><span class="yiyi-st" id="yiyi-122">其它与默认行为的区别,参见<em>shell</em> 和<em>executable</em> 参数。</span><span class="yiyi-st" id="yiyi-123">除非另外说明,建议传递一个序列给<em>args</em>。</span></p><p><span class="yiyi-st" id="yiyi-124">在POSIX上,如果<em>args</em>是字符串,则该字符串将被解释为要执行的程序的名称或路径。</span><span class="yiyi-st" id="yiyi-125">然而,这只能在不传递参数给程序时可行。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-126">注意</span></p><p><span class="yiyi-st" id="yiyi-127"><a class="reference internal" href="shlex.html#shlex.split" title="shlex.split"><code class="xref py py-meth docutils literal"><span class="pre">shlex.split()</span></code></a>在确定<em>args</em>的正确分词时很有用,尤其是在复杂情况下:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">shlex</span><span class="o">,</span> <span class="nn">subprocess</span>
|
||
<span class="gp">>>> </span><span class="n">command_line</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
|
||
<span class="go">/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"</span>
|
||
<span class="gp">>>> </span><span class="n">args</span> <span class="o">=</span> <span class="n">shlex</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">command_line</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="go">['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]</span>
|
||
<span class="gp">>>> </span><span class="n">p</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="c1"># Success!</span>
|
||
</code></pre><p class="last"><span class="yiyi-st" id="yiyi-128">特别要注意,shell中由空格分隔的选项(例如<em>-input</em>)和参数(例如<em>eggs.txt</em>)在不同的列表元素中,而shell中需要引号和反斜线转义的参数(例如包含空格的文件名和上面展示的<em>echo</em> 命令)是单一的列表元素。</span></p></div><p><span class="yiyi-st" id="yiyi-129">在Windows上,如果<em>args</em>是一个序列,则它将按照<a class="reference internal" href="#converting-argument-sequence"><span>将参数序列转换为Windows上的字符串</span></a>中所述的方式转换为字符串。</span><span class="yiyi-st" id="yiyi-130">这是因为底层的<code class="docutils literal"><span class="pre">CreateProcess()</span></code>对字符串进行操作。</span></p><p><span class="yiyi-st" id="yiyi-131"><em>shell</em> 参数(默认为<em>False</em>)指定是否使用shell来执行程序。</span><span class="yiyi-st" id="yiyi-132">如果<em>shell</em> 为<em>True</em>,则建议传递一个字符串而不是序列给<em>args</em>。</span></p><p><span class="yiyi-st" id="yiyi-133">在POSIX上,如果<code class="docutils literal"><span class="pre">shell=True</span></code>,则shell默认为<code class="file docutils literal"><span class="pre">/bin/sh</span></code>。</span><span class="yiyi-st" id="yiyi-134">如果<em>args</em> 是一个字符串,该字符串指定通过shell执行的命令。</span><span class="yiyi-st" id="yiyi-135">这意味着该字符串必须和在shell提示符中输入的格式完全一致。</span><span class="yiyi-st" id="yiyi-136">包括,例如,引号和反斜线转义文件名中的空格。</span><span class="yiyi-st" id="yiyi-137">如果<em>args</em>是一个序列,第一个元素指定命令行字符串,其它额外的任何元素将作为shell本身的额外的参数。</span><span class="yiyi-st" id="yiyi-138">也就是说,<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>相当于:</span></p><pre><code class="language-python"><span></span><span class="n">Popen</span><span class="p">([</span><span class="s1">'/bin/sh'</span><span class="p">,</span> <span class="s1">'-c'</span><span class="p">,</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="o">...</span><span class="p">])</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-139">在Windows上,如果<code class="docutils literal"><span class="pre">shell=True</span></code>,<span class="target" id="index-2"></span><code class="xref std std-envvar docutils literal"><span class="pre">COMSPEC</span></code>环境变量指定默认的shell。</span><span class="yiyi-st" id="yiyi-140">你需要在Windows上指定<code class="docutils literal"><span class="pre">shell=True</span></code>的唯一时候是当你希望执行的命令是shell中内置的(例如</span><span class="yiyi-st" id="yiyi-141"><strong class="command">dir</strong>或<strong class="command">copy</strong>)。</span><span class="yiyi-st" id="yiyi-142">你不需要<code class="docutils literal"><span class="pre">shell=True</span></code>来运行批处理文件或基于控制台的可执行文件。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-143">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-144">在使用<code class="docutils literal"><span class="pre">shell=True</span></code>之前,请先阅读<a class="reference internal" href="#security-considerations">安全注意事项</a>部分。</span></p></div><p><span class="yiyi-st" id="yiyi-145">在创建stdin/stdout/stderr管道文件对象时,<em>bufsize</em>将作为相应的参数提供给<a class="reference internal" href="functions.html#open" title="open"><code class="xref py py-func docutils literal"><span class="pre">open()</span></code></a>函数。</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-146"><code class="xref py py-const docutils literal"><span class="pre">0</span></code>表示无缓冲(读和写是一个系统调用,可以返回short)</span></li><li><span class="yiyi-st" id="yiyi-147"><code class="xref py py-const docutils literal"><span class="pre">1</span></code>表示行缓冲(仅在<code class="docutils literal"><span class="pre">universal_newlines=True</span></code>时可用,即以文本模式)</span></li><li><span class="yiyi-st" id="yiyi-148">任何其他正值表示使用大约该大小的缓冲器</span></li><li><span class="yiyi-st" id="yiyi-149">负bufsize(默认值)表示将使用io.DEFAULT_BUFFER_SIZE的系统默认值。</span></li></ul><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-150"><span class="versionmodified">在版本3.3.1中更改:</span> <em>bufsize</em>现在默认为-1,默认情况下启用缓冲以匹配大多数代码所期望的行为。</span><span class="yiyi-st" id="yiyi-151">在Python 3.2.4和3.3.1之前的版本中,它不正确地默认为<code class="xref py py-const docutils literal"><span class="pre">0</span></code>,这是未缓冲的,并允许短读。</span><span class="yiyi-st" id="yiyi-152">这是无意的,并且不匹配大多数代码预期的Python 2的行为。</span></p></div><p><span class="yiyi-st" id="yiyi-153"><em>executable</em> 参数指定一个要执行的替换程序。</span><span class="yiyi-st" id="yiyi-154">它很少需要用到。</span><span class="yiyi-st" id="yiyi-155">当<code class="docutils literal"><span class="pre">shell=False</span></code>时,<em>executable</em>替换由<em>args</em>指定的要执行的程序。</span><span class="yiyi-st" id="yiyi-156">但是,原始的<em>args</em> 仍然会传给该程序。</span><span class="yiyi-st" id="yiyi-157">大部分程序将<em>args</em> 当做命令的名字,它可以不同于真实执行的程序。</span><span class="yiyi-st" id="yiyi-158">在POSIX上,<em>args</em>的名称成为<strong class="program">ps</strong>等工具中显示的可执行文件名称。</span><span class="yiyi-st" id="yiyi-159">如果<code class="docutils literal"><span class="pre">shell=True</span></code>,则在POSIX上,<em>executable</em>参数指定默认<code class="file docutils literal"><span class="pre">/bin/sh</span></code>的替换shell。</span></p><p><span class="yiyi-st" id="yiyi-160"><em>stdin</em>、<em>stdout</em> 和<em>stderr</em> 分别指定程序的标准输入、标准输出和标准错误文件的句柄。</span><span class="yiyi-st" id="yiyi-161">有效值为<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>、<a class="reference internal" href="#subprocess.DEVNULL" title="subprocess.DEVNULL"><code class="xref py py-data docutils literal"><span class="pre">DEVNULL</span></code></a>、已经存在的文件描述器(正整数)、已经存在的<a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">文件对象</span></a>和<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-162"><a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>表示应该创建子进程的新管道。</span><span class="yiyi-st" id="yiyi-163"><a class="reference internal" href="#subprocess.DEVNULL" title="subprocess.DEVNULL"><code class="xref py py-data docutils literal"><span class="pre">DEVNULL</span></code></a>表示将使用特殊文件<a class="reference internal" href="os.html#os.devnull" title="os.devnull"><code class="xref py py-data docutils literal"><span class="pre">os.devnull</span></code></a>。</span><span class="yiyi-st" id="yiyi-164">使用默认设置<code class="docutils literal"><span class="pre">None</span></code>,不会发生重定向;子进程的文件句柄将从父进程继承。</span><span class="yiyi-st" id="yiyi-165">此外,<em>stderr</em>可以是<a class="reference internal" href="#subprocess.STDOUT" title="subprocess.STDOUT"><code class="xref py py-data docutils literal"><span class="pre">STDOUT</span></code></a>,这表示来自应用程序的stderr数据应该捕获到与stdout相同的文件句柄中。</span></p><p><span class="yiyi-st" id="yiyi-166"><em>preexec_fn</em> 如果设定为一个可调用对象,该对象将在子进程中在子进程执行之前调用。</span><span class="yiyi-st" id="yiyi-167">(仅POSIX)</span></p><div class="admonition warning"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-168">警告</span></p><p class="last"><span class="yiyi-st" id="yiyi-169">在应用程序中存在线程时,<em>preexec_fn</em>参数不安全。</span><span class="yiyi-st" id="yiyi-170">在调用exec之前,子进程可能死锁。</span><span class="yiyi-st" id="yiyi-171">如果你必须使用它,请保持它特别简单!</span><span class="yiyi-st" id="yiyi-172">最小化调用的库的数量。</span></p></div><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-173">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-174">如果需要修改子进程环境,请使用<em>env</em>参数,而不要在<em>preexec_fn</em>中修改。</span><span class="yiyi-st" id="yiyi-175"><em>start_new_session</em>参数可以取代先前常用的<em>preexec_fn</em>来在子进程中调用os.setsid()。</span></p></div><p><span class="yiyi-st" id="yiyi-176">如果<em>close_fds</em>为真,除了<code class="xref py py-const docutils literal"><span class="pre">0</span></code>、<code class="xref py py-const docutils literal"><span class="pre">1</span></code>和<code class="xref py py-const docutils literal"><span class="pre">2</span></code>之外的所有文件描述器都将在子进程执行之前关闭。</span><span class="yiyi-st" id="yiyi-177">(仅POSIX)。</span><span class="yiyi-st" id="yiyi-178">默认值因平台而异:在POSIX上始终为真。</span><span class="yiyi-st" id="yiyi-179">在Windows上,当<em>stdin</em>/<em>stdout</em>/<em>stderr</em>为<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>时为真,否则为假。</span><span class="yiyi-st" id="yiyi-180">在Windows上,如果<em>close_fds</em>为真,则子进程不会继承任何句柄。</span><span class="yiyi-st" id="yiyi-181">注意,在Windows上,你不可以设置<em>close_fds</em> 为真并同时通过设置<em>stdin</em>、<em>stdout</em> 或者<em>stderr</em>重定向标准句柄 。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-182"><span class="versionmodified">在版本3.2中已更改:</span> <em>close_fds</em>的默认值已从<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>更改为上述内容。</span></p></div><p><span class="yiyi-st" id="yiyi-183"><em>pass_fds</em>是一个可选的由文件描述符组成的序列,表示在父进程和子进程之间保持打开。</span><span class="yiyi-st" id="yiyi-184">传递任何<em>pass_fds</em>都将强制使得<em>close_fds</em>设置为<a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>。</span><span class="yiyi-st" id="yiyi-185">(仅POSIX)</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-186"><span class="versionmodified">版本3.2中的新功能:</span>添加了<em>pass_fds</em>参数。</span></p></div><p><span class="yiyi-st" id="yiyi-187">如果<em>cwd</em>不为<code class="docutils literal"><span class="pre">None</span></code>,则在执行子进程之前,该函数将工作目录更改为<em>cwd</em>。</span><span class="yiyi-st" id="yiyi-188">特别地,如果可执行路径是相对路径,则该函数寻找相对于<em>cwd</em>的<em>可执行文件</em>(或<em>args</em>中的第一个项目)。</span></p><p><span class="yiyi-st" id="yiyi-189">如果<em>restore_signals</em>为真(默认值),在子进程执行之前,将Python设置为SIG_IGN的所有信号在子进程中恢复为SIG_DFL。</span><span class="yiyi-st" id="yiyi-190">目前,这包括SIGPIPE、SIGXFZ和SIGXFSZ信号。</span><span class="yiyi-st" id="yiyi-191">(仅POSIX)</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-192"><span class="versionmodified">在版本3.2中已更改:</span>添加<em>restore_signals</em>。</span></p></div><p><span class="yiyi-st" id="yiyi-193">如果<em>start_new_session</em>为真,则在子进程中在执行子进程之前进行setsid()系统调用。</span><span class="yiyi-st" id="yiyi-194">(仅POSIX)</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-195"><span class="versionmodified">在版本3.2中已更改:</span>添加<em>start_new_session</em>。</span></p></div><p><span class="yiyi-st" id="yiyi-196">如果<em>env</em>不为<code class="docutils literal"><span class="pre">None</span></code>,则它必须是定义新进程的环境变量的映射;它们被用来代替继承当前进程环境这一默认行为。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-197">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-198">如果指定,<em>env</em> 必须提供要执行程序的任何变量。</span><span class="yiyi-st" id="yiyi-199">On Windows, in order to run a <a class="reference external" href="https://en.wikipedia.org/wiki/Side-by-Side_Assembly">side-by-side assembly</a> the specified <em>env</em> <strong>must</strong> include a valid <span class="target" id="index-3"></span><code class="xref std std-envvar docutils literal"><span class="pre">SystemRoot</span></code>.</span></p></div><p><span class="yiyi-st" id="yiyi-200">如果<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">True</span></code>,则文件对象<em>stdin</em>、<em>stdout</em>和<em>stderr</em>作为通用换行模式的文本流,如上述<a class="reference internal" href="#frequently-used-arguments"><span>常用参数</span></a>中所述,否则它们将作为二进制流打开。</span></p><p><span class="yiyi-st" id="yiyi-201">如果给定,<em>startupinfo</em>将是一个<a class="reference internal" href="#subprocess.STARTUPINFO" title="subprocess.STARTUPINFO"><code class="xref py py-class docutils literal"><span class="pre">STARTUPINFO</span></code></a>对象,它传递给底层的<code class="docutils literal"><span class="pre">CreateProcess</span></code>函数。</span><span class="yiyi-st" id="yiyi-202"><em>creationflags</em>(如果给定)可以是<a class="reference internal" href="#subprocess.CREATE_NEW_CONSOLE" title="subprocess.CREATE_NEW_CONSOLE"><code class="xref py py-data docutils literal"><span class="pre">CREATE_NEW_CONSOLE</span></code></a>或<a class="reference internal" href="#subprocess.CREATE_NEW_PROCESS_GROUP" title="subprocess.CREATE_NEW_PROCESS_GROUP"><code class="xref py py-data docutils literal"><span class="pre">CREATE_NEW_PROCESS_GROUP</span></code></a>。</span><span class="yiyi-st" id="yiyi-203">(只在Windows上)</span></p><p><span class="yiyi-st" id="yiyi-204">Popen对象通过<a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal"><span class="pre">with</span></code></a>语句支持上下文管理器:在退出时,标准文件描述器被关闭,进程被等待。</span></p><pre><code class="language-python"><span></span><span class="k">with</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">"ifconfig"</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span> <span class="k">as</span> <span class="n">proc</span><span class="p">:</span>
|
||
<span class="n">log</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">proc</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
|
||
</code></pre><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-205"><span class="versionmodified">在版本3.2中更改:</span>添加对上下文管理器的支持。</span></p></div></dd></dl></div><div class="section" id="exceptions"><h3><span class="yiyi-st" id="yiyi-206">17.5.1.3. </span><span class="yiyi-st" id="yiyi-207">异常</span></h3><p><span class="yiyi-st" id="yiyi-208">在子进程中引发的异常,在新程序开始执行之前将在父进程中被重新引发。</span><span class="yiyi-st" id="yiyi-209">此外,异常对象还将有一个名为<code class="xref py py-attr docutils literal"><span class="pre">child_traceback</span></code>的额外属性,该属性是一个字符串,包含来自子进程视角的回溯信息。</span></p><p><span class="yiyi-st" id="yiyi-210">最常见的异常是<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span><span class="yiyi-st" id="yiyi-211">例如,当试图执行一个不存在的文件时会发生该异常。</span><span class="yiyi-st" id="yiyi-212">应用程序应准备<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>异常的代码。</span></p><p><span class="yiyi-st" id="yiyi-213">如果使用不合法的参数调用<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>,则会引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-214">如果被调用的进程返回非零返回码,则<a class="reference internal" href="#subprocess.check_call" title="subprocess.check_call"><code class="xref py py-func docutils literal"><span class="pre">check_call()</span></code></a>和<a class="reference internal" href="#subprocess.check_output" title="subprocess.check_output"><code class="xref py py-func docutils literal"><span class="pre">check_output()</span></code></a>将引发<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-215">如果在进程退出之前超时,所有接受<em>timeout</em>参数的函数和方法都将引发<a class="reference internal" href="#subprocess.TimeoutExpired" title="subprocess.TimeoutExpired"><code class="xref py py-exc docutils literal"><span class="pre">TimeoutExpired </span></code></a>,例如<a class="reference internal" href="#subprocess.call" title="subprocess.call"><code class="xref py py-func docutils literal"><span class="pre">call()</span></code></a>和<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-216">此模块中定义的异常都继承自<a class="reference internal" href="#subprocess.SubprocessError" title="subprocess.SubprocessError"><code class="xref py py-exc docutils literal"><span class="pre">SubprocessError</span></code></a>。</span></p><span class="yiyi-st" id="yiyi-217"><blockquote><div><div class="versionadded"><p><span class="versionmodified">版本3.3中的新功能:</span>添加了<a class="reference internal" href="#subprocess.SubprocessError" title="subprocess.SubprocessError"><code class="xref py py-exc docutils literal"><span class="pre">SubprocessError</span></code></a>基类。</p></div></div></blockquote></span></div></div><div class="section" id="security-considerations"><h2><span class="yiyi-st" id="yiyi-218">17.5.2. </span><span class="yiyi-st" id="yiyi-219">安全性考虑</span></h2><p><span class="yiyi-st" id="yiyi-220">与其他popen函数不同,这个实现不会隐式调用系统shell。</span><span class="yiyi-st" id="yiyi-221">这意味着所有的字符包括shell元字符,都可以安全地传递给子进程。</span><span class="yiyi-st" id="yiyi-222">如果通过<code class="docutils literal"><span class="pre">shell=True</span></code>显式调用shell,则应用程序有责任确保所有空格和元字符都被适当引用以避免<a class="reference external" href="https://en.wikipedia.org/wiki/Shell_injection#Shell_injection">shell注入</a>漏洞。</span></p><p><span class="yiyi-st" id="yiyi-223">当使用<code class="docutils literal"><span class="pre">shell=True</span></code>时,可以使用<a class="reference internal" href="shlex.html#shlex.quote" title="shlex.quote"><code class="xref py py-func docutils literal"><span class="pre">shlex.quote()</span></code></a>函数正确地转义用于构建shell命令的字符串中的空格和shell元字符。</span></p></div><div class="section" id="popen-objects"><h2><span class="yiyi-st" id="yiyi-224">17.5.3. </span><span class="yiyi-st" id="yiyi-225">Popen对象</span></h2><p><span class="yiyi-st" id="yiyi-226"><a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>类的实例具有以下方法:</span></p><dl class="method"><dt id="subprocess.Popen.poll"><span class="yiyi-st" id="yiyi-227"> <code class="descclassname">Popen.</code><code class="descname">poll</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-228">检查子进程是否已经终止。</span><span class="yiyi-st" id="yiyi-229">设置并返回<a class="reference internal" href="#subprocess.Popen.returncode" title="subprocess.Popen.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>属性。</span></p></dd></dl><dl class="method"><dt id="subprocess.Popen.wait"><span class="yiyi-st" id="yiyi-230"> <code class="descclassname">Popen.</code><code class="descname">wait</code><span class="sig-paren">(</span><em>timeout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-231">等待子进程终止。</span><span class="yiyi-st" id="yiyi-232">设置并返回<a class="reference internal" href="#subprocess.Popen.returncode" title="subprocess.Popen.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>属性。</span></p><p><span class="yiyi-st" id="yiyi-233">如果进程在<em>timeout</em>秒后未终止,则引发<a class="reference internal" href="#subprocess.TimeoutExpired" title="subprocess.TimeoutExpired"><code class="xref py py-exc docutils literal"><span class="pre">TimeoutExpired</span></code></a>异常。</span><span class="yiyi-st" id="yiyi-234">捕获此异常并重试等待是安全的。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-235">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-236">当使用<code class="docutils literal"><span class="pre">stdout=PIPE</span></code>或<code class="docutils literal"><span class="pre">stderr=PIPE</span></code>时,如果子进程向管道生成足够的输出以致阻塞并等待操作系统管道缓冲区接受更多数据,将会死锁。</span><span class="yiyi-st" id="yiyi-237">在使用管道时,请使用<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">Popen.communicate()</span></code></a>来避免这个问题。</span></p></div><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-238">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-239">该函数使用频繁的循环(非阻塞调用和短暂休眠)实现。</span><span class="yiyi-st" id="yiyi-240">异步等待请使用<a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a>模块:请参阅<a class="reference internal" href="asyncio-subprocess.html#asyncio.create_subprocess_exec" title="asyncio.create_subprocess_exec"><code class="xref py py-class docutils literal"><span class="pre">asyncio.create_subprocess_exec</span></code></a>。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-241"><span class="versionmodified">在版本3.3中更改:</span>添加<em>timeout</em>。</span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-242"><span class="versionmodified">自版本3.4后已弃用:</span>不要使用<em>endtime</em>参数。</span><span class="yiyi-st" id="yiyi-243">它在3.3中是无意暴露的,但是没有文档,因为它是私有的供内部使用。</span><span class="yiyi-st" id="yiyi-244">请改用<em>timeout</em>。</span></p></div></dd></dl><dl class="method"><dt id="subprocess.Popen.communicate"><span class="yiyi-st" id="yiyi-245"> <code class="descclassname">Popen.</code><code class="descname">communicate</code><span class="sig-paren">(</span><em>input=None</em>, <em>timeout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-246">与进程交互:将数据发送到标准输入。</span><span class="yiyi-st" id="yiyi-247">从标准输出和标准错误读取数据,直至到达文件末尾。</span><span class="yiyi-st" id="yiyi-248">等待进程终止。</span><span class="yiyi-st" id="yiyi-249">可选的<em>input</em>参数应为要发送到子进程的数据,如果没有数据应发送到子进程则为<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-250"><em>input</em>的类型必须为字节,如果<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">True</span></code>,则为字符串。</span></p><p><span class="yiyi-st" id="yiyi-251"><a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">communicate()</span></code></a>返回一个<code class="docutils literal"><span class="pre">(stdout_data,</span> <span class="pre">stderr_data)</span></code>元组。</span><span class="yiyi-st" id="yiyi-252">这些数据是字节形式,如果<em>universal_newlines</em>为<code class="docutils literal"><span class="pre">True</span></code>,则为字符串。</span></p><p><span class="yiyi-st" id="yiyi-253">请注意,如果要将数据发送到进程的标准输入,则需要使用<code class="docutils literal"><span class="pre">stdin=PIPE</span></code>创建Popen对象。</span><span class="yiyi-st" id="yiyi-254">类似地,为了在结果元组中不只得到<code class="docutils literal"><span class="pre">None</span></code>,你还需要给予<code class="docutils literal"><span class="pre">stdout=PIPE</span></code>和/或<code class="docutils literal"><span class="pre">stderr=PIPE</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-255">如果进程在<em>timeout</em>秒后未终止,则会引发<a class="reference internal" href="#subprocess.TimeoutExpired" title="subprocess.TimeoutExpired"><code class="xref py py-exc docutils literal"><span class="pre">TimeoutExpired</span></code></a>异常。</span><span class="yiyi-st" id="yiyi-256">捕获此异常并重试通信将不会丢失任何输出。</span></p><p><span class="yiyi-st" id="yiyi-257">如果超时过期,子进程不会被终止,因此为了正确清理一个良好的应用程序应该杀死子进程并完成通信:</span></p><pre><code class="language-python"><span></span><span class="n">proc</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">outs</span><span class="p">,</span> <span class="n">errs</span> <span class="o">=</span> <span class="n">proc</span><span class="o">.</span><span class="n">communicate</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">15</span><span class="p">)</span>
|
||
<span class="k">except</span> <span class="n">TimeoutExpired</span><span class="p">:</span>
|
||
<span class="n">proc</span><span class="o">.</span><span class="n">kill</span><span class="p">()</span>
|
||
<span class="n">outs</span><span class="p">,</span> <span class="n">errs</span> <span class="o">=</span> <span class="n">proc</span><span class="o">.</span><span class="n">communicate</span><span class="p">()</span>
|
||
</code></pre><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-258">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-259">注意读取的数据是缓存在内存中的,所以如果数据大小很大或者无限制请不要使用这个方法。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-260"><span class="versionmodified">在版本3.3中更改:</span>添加<em>timeout</em>。</span></p></div></dd></dl><dl class="method"><dt id="subprocess.Popen.send_signal"><span class="yiyi-st" id="yiyi-261"> <code class="descclassname">Popen.</code><code class="descname">send_signal</code><span class="sig-paren">(</span><em>signal</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-262">发送信号<em>signal</em> 给子进程。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-263">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-264">在Windows上,SIGTERM是<a class="reference internal" href="#subprocess.Popen.terminate" title="subprocess.Popen.terminate"><code class="xref py py-meth docutils literal"><span class="pre">terminate()</span></code></a>的别名。</span><span class="yiyi-st" id="yiyi-265">CTRL_C_EVENT和CTRL_BREAK_EVENT可以发送给启动参数<em>creationflags</em> 包含<cite>CREATE_NEW_PROCESS_GROUP</cite> 的进程。</span></p></div></dd></dl><dl class="method"><dt id="subprocess.Popen.terminate"><span class="yiyi-st" id="yiyi-266"> <code class="descclassname">Popen.</code><code class="descname">terminate</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-267">终止子进程。</span><span class="yiyi-st" id="yiyi-268">在Posix操作系统上,该方法发送SIGTERM给子进程。</span><span class="yiyi-st" id="yiyi-269">在Windows上,调用Win32 API函数<code class="xref c c-func docutils literal"><span class="pre">TerminateProcess()</span></code>来停止子进程。</span></p></dd></dl><dl class="method"><dt id="subprocess.Popen.kill"><span class="yiyi-st" id="yiyi-270"> <code class="descclassname">Popen.</code><code class="descname">kill</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-271">杀死子进程。</span><span class="yiyi-st" id="yiyi-272">在Posix操作系统上,该函数发送SIGKILL给子进程。</span><span class="yiyi-st" id="yiyi-273">在Windows上,<a class="reference internal" href="#subprocess.Popen.kill" title="subprocess.Popen.kill"><code class="xref py py-meth docutils literal"><span class="pre">kill()</span></code></a>是<a class="reference internal" href="#subprocess.Popen.terminate" title="subprocess.Popen.terminate"><code class="xref py py-meth docutils literal"><span class="pre">terminate()</span></code></a>的别名。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-274">下面的属性也可以访问:</span></p><dl class="attribute"><dt id="subprocess.Popen.args"><span class="yiyi-st" id="yiyi-275"> <code class="descclassname">Popen.</code><code class="descname">args</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-276">传递给<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>的<em>args</em>参数 —— 程序参数序列或单个字符串。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-277"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="attribute"><dt id="subprocess.Popen.stdin"><span class="yiyi-st" id="yiyi-278"> <code class="descclassname">Popen.</code><code class="descname">stdin</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-279">如果<em>stdin</em>参数为<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性是由<a class="reference internal" href="functions.html#open" title="open"><code class="xref py py-func docutils literal"><span class="pre">open()</span></code></a>返回的可写流对象。</span><span class="yiyi-st" id="yiyi-280">如果<em>universal_newlines</em>参数为<code class="docutils literal"><span class="pre">True</span></code>,则流是文本流,否则为字节流。</span><span class="yiyi-st" id="yiyi-281">如果<em>stdin</em>参数不是<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.Popen.stdout"><span class="yiyi-st" id="yiyi-282"> <code class="descclassname">Popen.</code><code class="descname">stdout</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-283">如果<em>stdout</em>参数为<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性是由<a class="reference internal" href="functions.html#open" title="open"><code class="xref py py-func docutils literal"><span class="pre">open()</span></code></a>返回的可读流对象。</span><span class="yiyi-st" id="yiyi-284">从流读取将提供子进程的输出。</span><span class="yiyi-st" id="yiyi-285">如果<em>universal_newlines</em>参数为<code class="docutils literal"><span class="pre">True</span></code>,则流是文本流,否则为字节流。</span><span class="yiyi-st" id="yiyi-286">如果<em>stdout</em>参数不是<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.Popen.stderr"><span class="yiyi-st" id="yiyi-287"> <code class="descclassname">Popen.</code><code class="descname">stderr</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-288">如果<em>stderr</em>参数为<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性是由<a class="reference internal" href="functions.html#open" title="open"><code class="xref py py-func docutils literal"><span class="pre">open()</span></code></a>返回的可读流对象。</span><span class="yiyi-st" id="yiyi-289">从流读取将提供从子进程的错误输出。</span><span class="yiyi-st" id="yiyi-290">如果<em>universal_newlines</em>参数为<code class="docutils literal"><span class="pre">True</span></code>,则流是文本流,否则为字节流。</span><span class="yiyi-st" id="yiyi-291">如果<em>stderr</em>参数不是<a class="reference internal" href="#subprocess.PIPE" title="subprocess.PIPE"><code class="xref py py-data docutils literal"><span class="pre">PIPE</span></code></a>,则此属性为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl><div class="admonition warning"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-292">警告</span></p><p class="last"><span class="yiyi-st" id="yiyi-293">使用<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">communicate()</span></code></a>而不是<a class="reference internal" href="#subprocess.Popen.stdin" title="subprocess.Popen.stdin"><code class="xref py py-attr docutils literal"><span class="pre">.stdin.write</span></code></a>、<a class="reference internal" href="#subprocess.Popen.stdout" title="subprocess.Popen.stdout"><code class="xref py py-attr docutils literal"><span class="pre">.stdout.read</span></code></a>或<a class="reference internal" href="#subprocess.Popen.stderr" title="subprocess.Popen.stderr"><code class="xref py py-attr docutils literal"><span class="pre">.stderr.read</span></code></a>来避免由于任何其他OS管道缓冲区填满和阻塞子进程而导致的死锁。</span></p></div><dl class="attribute"><dt id="subprocess.Popen.pid"><span class="yiyi-st" id="yiyi-294"> <code class="descclassname">Popen.</code><code class="descname">pid</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-295">子进程的进程ID。</span></p><p><span class="yiyi-st" id="yiyi-296">请注意,如果将<em>shell</em>参数设置为<code class="docutils literal"><span class="pre">True</span></code>,那么这是生成的shell的进程ID。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.Popen.returncode"><span class="yiyi-st" id="yiyi-297"> <code class="descclassname">Popen.</code><code class="descname">returncode</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-298">由<a class="reference internal" href="#subprocess.Popen.poll" title="subprocess.Popen.poll"><code class="xref py py-meth docutils literal"><span class="pre">poll()</span></code></a>和<a class="reference internal" href="#subprocess.Popen.wait" title="subprocess.Popen.wait"><code class="xref py py-meth docutils literal"><span class="pre">wait()</span></code></a>(由<a class="reference internal" href="#subprocess.Popen.communicate" title="subprocess.Popen.communicate"><code class="xref py py-meth docutils literal"><span class="pre">communicate()</span></code></a>间接设置)的子进程的返回码。</span><span class="yiyi-st" id="yiyi-299"><code class="docutils literal"><span class="pre">None</span></code>值表示进程尚未终止。</span></p><p><span class="yiyi-st" id="yiyi-300">负值<code class="docutils literal"><span class="pre">-N</span></code>表示子进程被信号<code class="docutils literal"><span class="pre">N</span></code>终止(仅POSIX)。</span></p></dd></dl></div><div class="section" id="windows-popen-helpers"><h2><span class="yiyi-st" id="yiyi-301">17.5.4. </span><span class="yiyi-st" id="yiyi-302">Windows Popen的辅助类</span></h2><p><span class="yiyi-st" id="yiyi-303"><a class="reference internal" href="#subprocess.STARTUPINFO" title="subprocess.STARTUPINFO"><code class="xref py py-class docutils literal"><span class="pre">STARTUPINFO</span></code></a>类和以下常量仅在Windows上可用。</span></p><dl class="class"><dt id="subprocess.STARTUPINFO"><span class="yiyi-st" id="yiyi-304"> <em class="property">class </em><code class="descclassname">subprocess.</code><code class="descname">STARTUPINFO</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-305">部分支持Windows <a class="reference external" href="https://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx">STARTUPINFO</a>结构用于<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>创建。</span></p><dl class="attribute"><dt id="subprocess.STARTUPINFO.dwFlags"><span class="yiyi-st" id="yiyi-306"> <code class="descname">dwFlags</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-307">确定在进程创建窗口时是否使用某些<a class="reference internal" href="#subprocess.STARTUPINFO" title="subprocess.STARTUPINFO"><code class="xref py py-class docutils literal"><span class="pre">STARTUPINFO</span></code></a>属性的位字段。</span></p><pre><code class="language-python"><span></span><span class="n">si</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">STARTUPINFO</span><span class="p">()</span>
|
||
<span class="n">si</span><span class="o">.</span><span class="n">dwFlags</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">STARTF_USESTDHANDLES</span> <span class="o">|</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">STARTF_USESHOWWINDOW</span>
|
||
</code></pre></dd></dl><dl class="attribute"><dt id="subprocess.STARTUPINFO.hStdInput"><span class="yiyi-st" id="yiyi-308"> <code class="descname">hStdInput</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-309">如果<a class="reference internal" href="#subprocess.STARTUPINFO.dwFlags" title="subprocess.STARTUPINFO.dwFlags"><code class="xref py py-attr docutils literal"><span class="pre">dwFlags</span></code></a>指定<a class="reference internal" href="#subprocess.STARTF_USESTDHANDLES" title="subprocess.STARTF_USESTDHANDLES"><code class="xref py py-data docutils literal"><span class="pre">STARTF_USESTDHANDLES</span></code></a>,则此属性是进程的标准输入句柄。</span><span class="yiyi-st" id="yiyi-310">如果未指定<a class="reference internal" href="#subprocess.STARTF_USESTDHANDLES" title="subprocess.STARTF_USESTDHANDLES"><code class="xref py py-data docutils literal"><span class="pre">STARTF_USESTDHANDLES</span></code></a>,则标准输入的默认值为键盘缓冲区。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.STARTUPINFO.hStdOutput"><span class="yiyi-st" id="yiyi-311"> <code class="descname">hStdOutput</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-312">如果<a class="reference internal" href="#subprocess.STARTUPINFO.dwFlags" title="subprocess.STARTUPINFO.dwFlags"><code class="xref py py-attr docutils literal"><span class="pre">dwFlags</span></code></a>指定<a class="reference internal" href="#subprocess.STARTF_USESTDHANDLES" title="subprocess.STARTF_USESTDHANDLES"><code class="xref py py-data docutils literal"><span class="pre">STARTF_USESTDHANDLES</span></code></a>,则此属性是进程的标准输出句柄。</span><span class="yiyi-st" id="yiyi-313">否则,忽略该属性且默认的标准输出为控制台窗口的缓冲区。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.STARTUPINFO.hStdError"><span class="yiyi-st" id="yiyi-314"> <code class="descname">hStdError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-315">如果<a class="reference internal" href="#subprocess.STARTUPINFO.dwFlags" title="subprocess.STARTUPINFO.dwFlags"><code class="xref py py-attr docutils literal"><span class="pre">dwFlags</span></code></a>指定<a class="reference internal" href="#subprocess.STARTF_USESTDHANDLES" title="subprocess.STARTF_USESTDHANDLES"><code class="xref py py-data docutils literal"><span class="pre">STARTF_USESTDHANDLES</span></code></a>,则此属性是进程的标准错误句柄。</span><span class="yiyi-st" id="yiyi-316">否则,忽略该属性且默认的标准错误输出为控制台窗口的缓冲区。</span></p></dd></dl><dl class="attribute"><dt id="subprocess.STARTUPINFO.wShowWindow"><span class="yiyi-st" id="yiyi-317"> <code class="descname">wShowWindow</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-318">如果<a class="reference internal" href="#subprocess.STARTUPINFO.dwFlags" title="subprocess.STARTUPINFO.dwFlags"><code class="xref py py-attr docutils literal"><span class="pre">dwFlags</span></code></a>指定<a class="reference internal" href="#subprocess.STARTF_USESHOWWINDOW" title="subprocess.STARTF_USESHOWWINDOW"><code class="xref py py-data docutils literal"><span class="pre">STARTF_USESHOWWINDOW</span></code></a>,则此属性可以是<code class="docutils literal"><span class="pre">nCmdShow</span></code>参数中为<a class="reference external" href="https://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx">ShowWindow</a>函数指定的任何值,除了<code class="docutils literal"><span class="pre">SW_SHOWDEFAULT</span></code>。</span><span class="yiyi-st" id="yiyi-319">否则,忽略该属性。</span></p><p><span class="yiyi-st" id="yiyi-320">为此属性提供了<a class="reference internal" href="#subprocess.SW_HIDE" title="subprocess.SW_HIDE"><code class="xref py py-data docutils literal"><span class="pre">SW_HIDE</span></code></a>。</span><span class="yiyi-st" id="yiyi-321">当<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>使用<code class="docutils literal"><span class="pre">shell=True</span></code>调用时使用。</span></p></dd></dl></dd></dl><div class="section" id="constants"><h3><span class="yiyi-st" id="yiyi-322">17.5.4.1. </span><span class="yiyi-st" id="yiyi-323">常量</span></h3><p><span class="yiyi-st" id="yiyi-324"><a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块公开以下常量。</span></p><dl class="data"><dt id="subprocess.STD_INPUT_HANDLE"><span class="yiyi-st" id="yiyi-325"> <code class="descclassname">subprocess.</code><code class="descname">STD_INPUT_HANDLE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-326">标准输入设备。</span><span class="yiyi-st" id="yiyi-327">最初,这是控制台输入缓冲区,<code class="docutils literal"><span class="pre">CONIN$</span></code>。</span></p></dd></dl><dl class="data"><dt id="subprocess.STD_OUTPUT_HANDLE"><span class="yiyi-st" id="yiyi-328"> <code class="descclassname">subprocess.</code><code class="descname">STD_OUTPUT_HANDLE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-329">标准输出设备。</span><span class="yiyi-st" id="yiyi-330">最初,这是活动控制台屏幕缓冲区,<code class="docutils literal"><span class="pre">CONOUT$</span></code>。</span></p></dd></dl><dl class="data"><dt id="subprocess.STD_ERROR_HANDLE"><span class="yiyi-st" id="yiyi-331"> <code class="descclassname">subprocess.</code><code class="descname">STD_ERROR_HANDLE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-332">标准错误设备。</span><span class="yiyi-st" id="yiyi-333">最初,这是活动控制台屏幕缓冲区,<code class="docutils literal"><span class="pre">CONOUT$</span></code>。</span></p></dd></dl><dl class="data"><dt id="subprocess.SW_HIDE"><span class="yiyi-st" id="yiyi-334"> <code class="descclassname">subprocess.</code><code class="descname">SW_HIDE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-335">隐藏窗口。</span><span class="yiyi-st" id="yiyi-336">另外一个窗口将被激活。</span></p></dd></dl><dl class="data"><dt id="subprocess.STARTF_USESTDHANDLES"><span class="yiyi-st" id="yiyi-337"> <code class="descclassname">subprocess.</code><code class="descname">STARTF_USESTDHANDLES</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-338">表示<a class="reference internal" href="#subprocess.STARTUPINFO.hStdInput" title="subprocess.STARTUPINFO.hStdInput"><code class="xref py py-attr docutils literal"><span class="pre">STARTUPINFO.hStdInput</span></code></a>、<a class="reference internal" href="#subprocess.STARTUPINFO.hStdOutput" title="subprocess.STARTUPINFO.hStdOutput"><code class="xref py py-attr docutils literal"><span class="pre">STARTUPINFO.hStdOutput</span></code></a>和<a class="reference internal" href="#subprocess.STARTUPINFO.hStdError" title="subprocess.STARTUPINFO.hStdError"><code class="xref py py-attr docutils literal"><span class="pre">STARTUPINFO.hStdError</span></code></a>属性包含其他信息。</span></p></dd></dl><dl class="data"><dt id="subprocess.STARTF_USESHOWWINDOW"><span class="yiyi-st" id="yiyi-339"> <code class="descclassname">subprocess.</code><code class="descname">STARTF_USESHOWWINDOW</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-340">表示<a class="reference internal" href="#subprocess.STARTUPINFO.wShowWindow" title="subprocess.STARTUPINFO.wShowWindow"><code class="xref py py-attr docutils literal"><span class="pre">STARTUPINFO.wShowWindow</span></code></a>属性包含附加信息。</span></p></dd></dl><dl class="data"><dt id="subprocess.CREATE_NEW_CONSOLE"><span class="yiyi-st" id="yiyi-341"> <code class="descclassname">subprocess.</code><code class="descname">CREATE_NEW_CONSOLE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-342">新的进程将具有一个新的控制台,而不是继承它父进程的控制台(默认行为)。</span></p></dd></dl><dl class="data"><dt id="subprocess.CREATE_NEW_PROCESS_GROUP"><span class="yiyi-st" id="yiyi-343"> <code class="descclassname">subprocess.</code><code class="descname">CREATE_NEW_PROCESS_GROUP</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-344">一个<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a> <code class="docutils literal"><span class="pre">creationflags</span></code>参数,以指定将创建一个新进程组。</span><span class="yiyi-st" id="yiyi-345">在子进程上使用<a class="reference internal" href="os.html#os.kill" title="os.kill"><code class="xref py py-func docutils literal"><span class="pre">os.kill()</span></code></a>时,此标志是必需的。</span></p><p><span class="yiyi-st" id="yiyi-346">如果指定<a class="reference internal" href="#subprocess.CREATE_NEW_CONSOLE" title="subprocess.CREATE_NEW_CONSOLE"><code class="xref py py-data docutils literal"><span class="pre">CREATE_NEW_CONSOLE</span></code></a>,则忽略此标志。</span></p></dd></dl></div></div><div class="section" id="older-high-level-api"><h2><span class="yiyi-st" id="yiyi-347">17.5.5. </span><span class="yiyi-st" id="yiyi-348">旧式的高级API </span></h2><p><span class="yiyi-st" id="yiyi-349">在Python 3.5之前,subprocess的高级API包含下面这三个函数。</span><span class="yiyi-st" id="yiyi-350">现在可以在许多情况下使用<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">run()</span></code></a>,但大量现有代码仍然调用这些函数。</span></p><dl class="function"><dt id="subprocess.call"><span class="yiyi-st" id="yiyi-351"> <code class="descclassname">subprocess.</code><code class="descname">call</code><span class="sig-paren">(</span><em>args</em>, <em>*</em>, <em>stdin=None</em>, <em>stdout=None</em>, <em>stderr=None</em>, <em>shell=False</em>, <em>timeout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-352">执行<em>args</em> 描述的命令。</span><span class="yiyi-st" id="yiyi-353">等待命令完成,然后返回<a class="reference internal" href="#subprocess.Popen.returncode" title="subprocess.Popen.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>属性。</span></p><p><span class="yiyi-st" id="yiyi-354">这相当于:</span></p><pre><code class="language-python"><span></span><span class="n">run</span><span class="p">(</span><span class="o">...</span><span class="p">)</span><span class="o">.</span><span class="n">returncode</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-355">(但不支持<em>input</em>和<em>check</em>参数)</span></p><p><span class="yiyi-st" id="yiyi-356">上面显示的参数只是最常见的参数。</span><span class="yiyi-st" id="yiyi-357">完整的函数形式很大程度上与<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>构造函数相同 —— 除<em>timeout</em>之外,该函数的所有参数都直接传递给Popen接口。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-358">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-359">请勿使用<code class="docutils literal"><span class="pre">stdout=PIPE</span></code>或<code class="docutils literal"><span class="pre">stderr=PIPE</span></code>调用用此函数。</span><span class="yiyi-st" id="yiyi-360">如果子进程生成足够的输出到一个管道并由于管道没有被读取而充满OS管道缓冲区,该子进程将阻塞。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-361"><span class="versionmodified">在版本3.3中更改:</span>添加<em>timeout</em>。</span></p></div></dd></dl><dl class="function"><dt id="subprocess.check_call"><span class="yiyi-st" id="yiyi-362"> <code class="descclassname">subprocess.</code><code class="descname">check_call</code><span class="sig-paren">(</span><em>args</em>, <em>*</em>, <em>stdin=None</em>, <em>stdout=None</em>, <em>stderr=None</em>, <em>shell=False</em>, <em>timeout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-363">执行带参数的命令。</span><span class="yiyi-st" id="yiyi-364">等待命令完成。</span><span class="yiyi-st" id="yiyi-365">如果返回码为零则返回,否则引发<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>。</span><span class="yiyi-st" id="yiyi-366"><a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>对象将返回码放在在<a class="reference internal" href="#subprocess.CalledProcessError.returncode" title="subprocess.CalledProcessError.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>属性中。</span></p><p><span class="yiyi-st" id="yiyi-367">这相当于:</span></p><pre><code class="language-python"><span></span><span class="n">run</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-368">(除了不支持<em>input</em>参数)</span></p><p><span class="yiyi-st" id="yiyi-369">上面显示的参数只是最常见的参数。</span><span class="yiyi-st" id="yiyi-370">完整的函数形式很大程度上与<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>构造函数相同 —— 除<em>timeout</em>之外,该函数的所有参数都直接传递给Popen接口。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-371">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-372">请勿使用<code class="docutils literal"><span class="pre">stdout=PIPE</span></code>或<code class="docutils literal"><span class="pre">stderr=PIPE</span></code>调用此函数。</span><span class="yiyi-st" id="yiyi-373">如果子进程生成足够的输出到一个管道并由于管道没有被读取而充满OS管道缓冲区,该子进程将阻塞。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-374"><span class="versionmodified">在版本3.3中更改:</span>添加<em>timeout</em>。</span></p></div></dd></dl><dl class="function"><dt id="subprocess.check_output"><span class="yiyi-st" id="yiyi-375"> <code class="descclassname">subprocess.</code><code class="descname">check_output</code><span class="sig-paren">(</span><em>args</em>, <em>*</em>, <em>stdin=None</em>, <em>stderr=None</em>, <em>shell=False</em>, <em>universal_newlines=False</em>, <em>timeout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-376">使用参数运行命令并返回其输出。</span></p><p><span class="yiyi-st" id="yiyi-377">如果返回码非零,它将引发一个<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>。</span><span class="yiyi-st" id="yiyi-378"><a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>对象将返回码放在在<a class="reference internal" href="#subprocess.CalledProcessError.returncode" title="subprocess.CalledProcessError.returncode"><code class="xref py py-attr docutils literal"><span class="pre">returncode</span></code></a>属性中,输出放在<a class="reference internal" href="#subprocess.CalledProcessError.output" title="subprocess.CalledProcessError.output"><code class="xref py py-attr docutils literal"><span class="pre">output</span></code></a>属性中。</span></p><p><span class="yiyi-st" id="yiyi-379">这相当于:</span></p><pre><code class="language-python"><span></span><span class="n">run</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span><span class="o">.</span><span class="n">stdout</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-380">上面显示的参数只是最常见的参数。</span><span class="yiyi-st" id="yiyi-381">完整的函数形式很大程度上与<a class="reference internal" href="#subprocess.run" title="subprocess.run"><code class="xref py py-func docutils literal"><span class="pre">Popen</span></code></a>构造函数相同 —— 该函数的大部分参数都直接传递给Popen接口。</span><span class="yiyi-st" id="yiyi-382">但是,不支持显式传递<code class="docutils literal"><span class="pre">input=None</span></code>来继承父进程的标准输入文件句柄。</span></p><p><span class="yiyi-st" id="yiyi-383">默认情况下,此函数将以编码的字节返回数据。</span><span class="yiyi-st" id="yiyi-384">输出数据的实际编码可以取决于被调用的命令,因此对文本的解码通常需要在应用程序级处理。</span></p><p><span class="yiyi-st" id="yiyi-385">可通过将<em>universal_newlines</em>设置为<code class="docutils literal"><span class="pre">True</span></code>来覆盖此行为,如上述<a class="reference internal" href="#frequently-used-arguments"><span>常用参数</span></a>中所述。</span></p><p><span class="yiyi-st" id="yiyi-386">要在结果中捕获标准错误,请使用<code class="docutils literal"><span class="pre">stderr=subprocess.STDOUT</span></code>:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">check_output</span><span class="p">(</span>
|
||
<span class="gp">... </span> <span class="s2">"ls non_existent_file; exit 0"</span><span class="p">,</span>
|
||
<span class="gp">... </span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">STDOUT</span><span class="p">,</span>
|
||
<span class="gp">... </span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="go">'ls: non_existent_file: No such file or directory\n'</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-387"><span class="versionmodified">版本3.1中的新功能。</span></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-388"><span class="versionmodified">在版本3.3中更改:</span>添加<em>timeout</em>。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-389"><span class="versionmodified">在版本3.4中更改:</span>添加对<em>input</em>关键字参数的支持。</span></p></div></dd></dl></div><div class="section" id="replacing-older-functions-with-the-subprocess-module"><h2><span class="yiyi-st" id="yiyi-390">17.5.6. </span><span class="yiyi-st" id="yiyi-391">使用<a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块替换旧的函数</span></h2><p><span class="yiyi-st" id="yiyi-392">在本小节中,“a变为b”的意思是b可以作为a的一种替换使用。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-393">注意</span></p><p><span class="yiyi-st" id="yiyi-394">如果无法找到执行的程序,则本节中的所有“a”函数都会失败(或多或少); “b”替换则引发<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>。</span></p><p class="last"><span class="yiyi-st" id="yiyi-395">此外,如果请求的操作产生非零返回代码,则使用<a class="reference internal" href="#subprocess.check_output" title="subprocess.check_output"><code class="xref py py-func docutils literal"><span class="pre">check_output()</span></code></a>的替换将失败并显示<a class="reference internal" href="#subprocess.CalledProcessError" title="subprocess.CalledProcessError"><code class="xref py py-exc docutils literal"><span class="pre">CalledProcessError</span></code></a>。</span><span class="yiyi-st" id="yiyi-396">输出仍然可以在引发的异常的<a class="reference internal" href="#subprocess.CalledProcessError.output" title="subprocess.CalledProcessError.output"><code class="xref py py-attr docutils literal"><span class="pre">output</span></code></a>属性中访问。</span></p></div><p><span class="yiyi-st" id="yiyi-397">在以下示例中,我们假设相关函数已从<a class="reference internal" href="#module-subprocess" title="subprocess: Subprocess management."><code class="xref py py-mod docutils literal"><span class="pre">subprocess</span></code></a>模块导入。</span></p><div class="section" id="replacing-bin-sh-shell-backquote"><h3><span class="yiyi-st" id="yiyi-398">17.5.6.1. </span><span class="yiyi-st" id="yiyi-399">替换/bin/sh shell反引号</span></h3><div class="highlight-bash"><div class="highlight"><pre><span></span><span class="nv">output</span><span class="o">=</span><span class="sb">`</span>mycmd myarg<span class="sb">`</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-400">变为:</span></p><pre><code class="language-python"><span></span><span class="n">output</span> <span class="o">=</span> <span class="n">check_output</span><span class="p">([</span><span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">])</span>
|
||
</code></pre></div><div class="section" id="replacing-shell-pipeline"><h3><span class="yiyi-st" id="yiyi-401">17.5.6.2. </span><span class="yiyi-st" id="yiyi-402">替换shell管道</span></h3><div class="highlight-bash"><div class="highlight"><pre><span></span><span class="nv">output</span><span class="o">=</span><span class="sb">`</span>dmesg <span class="p">|</span> grep hda<span class="sb">`</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-403">变为:</span></p><pre><code class="language-python"><span></span><span class="n">p1</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">"dmesg"</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
|
||
<span class="n">p2</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">"grep"</span><span class="p">,</span> <span class="s2">"hda"</span><span class="p">],</span> <span class="n">stdin</span><span class="o">=</span><span class="n">p1</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
|
||
<span class="n">p1</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># Allow p1 to receive a SIGPIPE if p2 exits.</span>
|
||
<span class="n">output</span> <span class="o">=</span> <span class="n">p2</span><span class="o">.</span><span class="n">communicate</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-404">在p2之后调用p1.stdout.close() 是非常重要的,这样,如果p2在 p1之前退出p1可以收到一个SIGPIPE信号。</span></p><p><span class="yiyi-st" id="yiyi-405">另外一种方法,对于可信任的输入,也可以直接使用shell自己对管道的支持:</span></p><div class="highlight-bash"><div class="highlight"><pre><span></span><span class="nv">output</span><span class="o">=</span><span class="sb">`</span>dmesg <span class="p">|</span> grep hda<span class="sb">`</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-406">变为:</span></p><pre><code class="language-python"><span></span><span class="n">output</span><span class="o">=</span><span class="n">check_output</span><span class="p">(</span><span class="s2">"dmesg | grep hda"</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
</code></pre></div><div class="section" id="replacing-os-system"><h3><span class="yiyi-st" id="yiyi-407">17.5.6.3. </span><span class="yiyi-st" id="yiyi-408">替换<a class="reference internal" href="os.html#os.system" title="os.system"><code class="xref py py-func docutils literal"><span class="pre">os.system()</span></code></a> </span></h3><pre><code class="language-python"><span></span><span class="n">sts</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"mycmd"</span> <span class="o">+</span> <span class="s2">" myarg"</span><span class="p">)</span>
|
||
<span class="c1"># becomes</span>
|
||
<span class="n">sts</span> <span class="o">=</span> <span class="n">call</span><span class="p">(</span><span class="s2">"mycmd"</span> <span class="o">+</span> <span class="s2">" myarg"</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-409">注意:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-410">通常不需要通过shell调用程序</span></li></ul><p><span class="yiyi-st" id="yiyi-411">更真实的例子可能像这样:</span></p><pre><code class="language-python"><span></span><span class="k">try</span><span class="p">:</span>
|
||
<span class="n">retcode</span> <span class="o">=</span> <span class="n">call</span><span class="p">(</span><span class="s2">"mycmd"</span> <span class="o">+</span> <span class="s2">" myarg"</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">retcode</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Child was terminated by signal"</span><span class="p">,</span> <span class="o">-</span><span class="n">retcode</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Child returned"</span><span class="p">,</span> <span class="n">retcode</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
||
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Execution failed:"</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
||
</code></pre></div><div class="section" id="replacing-the-os-spawn-family"><h3><span class="yiyi-st" id="yiyi-412">17.5.6.4. </span><span class="yiyi-st" id="yiyi-413">替换<a class="reference internal" href="os.html#os.spawnl" title="os.spawnl"><code class="xref py py-func docutils literal"><span class="pre">os.spawn</span></code></a>系列</span></h3><p><span class="yiyi-st" id="yiyi-414">P_NOWAIT 示例:</span></p><pre><code class="language-python"><span></span><span class="n">pid</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">spawnlp</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">P_NOWAIT</span><span class="p">,</span> <span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">pid</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">])</span><span class="o">.</span><span class="n">pid</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-415">P_WAIT 示例:</span></p><pre><code class="language-python"><span></span><span class="n">retcode</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">spawnlp</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">P_WAIT</span><span class="p">,</span> <span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">retcode</span> <span class="o">=</span> <span class="n">call</span><span class="p">([</span><span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">])</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-416">向量示例:</span></p><pre><code class="language-python"><span></span><span class="n">os</span><span class="o">.</span><span class="n">spawnvp</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">P_NOWAIT</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">Popen</span><span class="p">([</span><span class="n">path</span><span class="p">]</span> <span class="o">+</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-417">环境变量示例:</span></p><pre><code class="language-python"><span></span><span class="n">os</span><span class="o">.</span><span class="n">spawnlpe</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">P_NOWAIT</span><span class="p">,</span> <span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">Popen</span><span class="p">([</span><span class="s2">"/bin/mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">],</span> <span class="n">env</span><span class="o">=</span><span class="p">{</span><span class="s2">"PATH"</span><span class="p">:</span> <span class="s2">"/usr/bin"</span><span class="p">})</span>
|
||
</code></pre></div><div class="section" id="replacing-os-popen-os-popen2-os-popen3"><h3><span class="yiyi-st" id="yiyi-418">17.5.6.5. </span><span class="yiyi-st" id="yiyi-419">替换<a class="reference internal" href="os.html#os.popen" title="os.popen"><code class="xref py py-func docutils literal"><span class="pre">os.popen()</span></code></a>、<code class="xref py py-func docutils literal"><span class="pre">os.popen2()</span></code>、<code class="xref py py-func docutils literal"><span class="pre">os.popen3()</span></code></span></h3><pre><code class="language-python"><span></span><span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span> <span class="n">child_stdout</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">popen2</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">bufsize</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bufsize</span><span class="o">=</span><span class="n">bufsize</span><span class="p">,</span>
|
||
<span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">close_fds</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span> <span class="n">child_stdout</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="p">)</span>
|
||
</code></pre><pre><code class="language-python"><span></span><span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span>
|
||
<span class="n">child_stdout</span><span class="p">,</span>
|
||
<span class="n">child_stderr</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">popen3</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">bufsize</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bufsize</span><span class="o">=</span><span class="n">bufsize</span><span class="p">,</span>
|
||
<span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">close_fds</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span>
|
||
<span class="n">child_stdout</span><span class="p">,</span>
|
||
<span class="n">child_stderr</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
||
</code></pre><pre><code class="language-python"><span></span><span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span> <span class="n">child_stdout_and_stderr</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">popen4</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">bufsize</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bufsize</span><span class="o">=</span><span class="n">bufsize</span><span class="p">,</span>
|
||
<span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">STDOUT</span><span class="p">,</span> <span class="n">close_fds</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">child_stdin</span><span class="p">,</span> <span class="n">child_stdout_and_stderr</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-420">返回码的处理可以转换成下面的方式:</span></p><pre><code class="language-python"><span></span><span class="n">pipe</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
|
||
<span class="o">...</span>
|
||
<span class="n">rc</span> <span class="o">=</span> <span class="n">pipe</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="n">rc</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">rc</span> <span class="o">>></span> <span class="mi">8</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"There were some errors"</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">process</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
|
||
<span class="o">...</span>
|
||
<span class="n">process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="n">process</span><span class="o">.</span><span class="n">wait</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"There were some errors"</span><span class="p">)</span>
|
||
</code></pre></div><div class="section" id="replacing-functions-from-the-popen2-module"><h3><span class="yiyi-st" id="yiyi-421">17.5.6.6. </span><span class="yiyi-st" id="yiyi-422">替换<code class="xref py py-mod docutils literal"><span class="pre">popen2</span></code>模块中的函数</span></h3><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-423">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-424">如果popen2函数的cmd参数是字符串,则通过/bin/sh执行该命令。</span><span class="yiyi-st" id="yiyi-425">如果是列表,则直接执行命令。</span></p></div><pre><code class="language-python"><span></span><span class="p">(</span><span class="n">child_stdout</span><span class="p">,</span> <span class="n">child_stdin</span><span class="p">)</span> <span class="o">=</span> <span class="n">popen2</span><span class="o">.</span><span class="n">popen2</span><span class="p">(</span><span class="s2">"somestring"</span><span class="p">,</span> <span class="n">bufsize</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">(</span><span class="s2">"somestring"</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bufsize</span><span class="o">=</span><span class="n">bufsize</span><span class="p">,</span>
|
||
<span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">close_fds</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">child_stdout</span><span class="p">,</span> <span class="n">child_stdin</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="p">)</span>
|
||
</code></pre><pre><code class="language-python"><span></span><span class="p">(</span><span class="n">child_stdout</span><span class="p">,</span> <span class="n">child_stdin</span><span class="p">)</span> <span class="o">=</span> <span class="n">popen2</span><span class="o">.</span><span class="n">popen2</span><span class="p">([</span><span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">],</span> <span class="n">bufsize</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
|
||
<span class="o">==></span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">"mycmd"</span><span class="p">,</span> <span class="s2">"myarg"</span><span class="p">],</span> <span class="n">bufsize</span><span class="o">=</span><span class="n">bufsize</span><span class="p">,</span>
|
||
<span class="n">stdin</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">close_fds</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">child_stdout</span><span class="p">,</span> <span class="n">child_stdin</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-426"><code class="xref py py-class docutils literal"><span class="pre">popen2.Popen3</span></code>和<code class="xref py py-class docutils literal"><span class="pre">popen2.Popen4</span></code>工作方式基本上类似于<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">subprocess.Popen</span></code></a>,除了以下几点:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-427"><a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>如果执行失败,则引发异常。</span></li><li><span class="yiyi-st" id="yiyi-428"><em>capturestderr</em> 参数替换成<em>stderr</em> 参数。</span></li><li><span class="yiyi-st" id="yiyi-429"><code class="docutils literal"><span class="pre">stdin=PIPE</span></code>和<code class="docutils literal"><span class="pre">stdout=PIPE</span></code>必须指定。</span></li><li><span class="yiyi-st" id="yiyi-430">popen2默认关闭所有文件描述器,但你必须用<a class="reference internal" href="#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal"><span class="pre">Popen</span></code></a>指定<code class="docutils literal"><span class="pre">close_fds=True</span></code>以保证在所有平台或过去的Python版本上的行为。</span></li></ul></div></div><div class="section" id="legacy-shell-invocation-functions"><h2><span class="yiyi-st" id="yiyi-431">17.5.7. </span><span class="yiyi-st" id="yiyi-432">传统Shell调用函数</span></h2><p><span class="yiyi-st" id="yiyi-433">该模块还提供以下的来自2.x <code class="docutils literal"><span class="pre">commands</span></code>模块的旧式函数。</span><span class="yiyi-st" id="yiyi-434">这些操作隐式调用系统shell,并且上述关于安全性和异常处理一致性的保证都不对这些函数有效。</span></p><dl class="function"><dt id="subprocess.getstatusoutput"><span class="yiyi-st" id="yiyi-435"> <code class="descclassname">subprocess.</code><code class="descname">getstatusoutput</code><span class="sig-paren">(</span><em>cmd</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-436">返回在shell中执行<em>cmd</em>的<code class="docutils literal"><span class="pre">(status,</span> <span class="pre">output)</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-437">用<code class="xref py py-meth docutils literal"><span class="pre">Popen.check_output()</span></code>在shell中执行字符串<em>cmd</em>,并返回一个二元组<code class="docutils literal"><span class="pre">(status,</span> <span class="pre">output)</span></code>。</span><span class="yiyi-st" id="yiyi-438">使用通用换行模式;有关详细信息,请参阅<a class="reference internal" href="#frequently-used-arguments"><span>常用参数</span></a>上的说明。</span></p><p><span class="yiyi-st" id="yiyi-439">从输出中去除尾部换行符。</span><span class="yiyi-st" id="yiyi-440">可以根据C函数<code class="xref c c-func docutils literal"><span class="pre">wait()</span></code>的规则解释命令的退出状态。</span><span class="yiyi-st" id="yiyi-441">例如:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">getstatusoutput</span><span class="p">(</span><span class="s1">'ls /bin/ls'</span><span class="p">)</span>
|
||
<span class="go">(0, '/bin/ls')</span>
|
||
<span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">getstatusoutput</span><span class="p">(</span><span class="s1">'cat /bin/junk'</span><span class="p">)</span>
|
||
<span class="go">(256, 'cat: /bin/junk: No such file or directory')</span>
|
||
<span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">getstatusoutput</span><span class="p">(</span><span class="s1">'/bin/junk'</span><span class="p">)</span>
|
||
<span class="go">(256, 'sh: /bin/junk: not found')</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-442">可用的平台:POSIX&Windows</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-443"><span class="versionmodified">在版本3.3.4中更改:</span>添加了Windows的支持</span></p></div></dd></dl><dl class="function"><dt id="subprocess.getoutput"><span class="yiyi-st" id="yiyi-444"> <code class="descclassname">subprocess.</code><code class="descname">getoutput</code><span class="sig-paren">(</span><em>cmd</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-445">返回在shell中执行<em>cmd</em>的输出(标准输出和标准错误)。</span></p><p><span class="yiyi-st" id="yiyi-446">类似<a class="reference internal" href="#subprocess.getstatusoutput" title="subprocess.getstatusoutput"><code class="xref py py-func docutils literal"><span class="pre">getstatusoutput()</span></code></a>,除了退出状态被忽略,返回值是一个包含命令输出的字符串。</span><span class="yiyi-st" id="yiyi-447">例如:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">subprocess</span><span class="o">.</span><span class="n">getoutput</span><span class="p">(</span><span class="s1">'ls /bin/ls'</span><span class="p">)</span>
|
||
<span class="go">'/bin/ls'</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-448">可用的平台:POSIX&Windows</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-449"><span class="versionmodified">在版本3.3.4中更改:</span>添加了Windows的支持</span></p></div></dd></dl></div><div class="section" id="notes"><h2><span class="yiyi-st" id="yiyi-450">17.5.8. </span><span class="yiyi-st" id="yiyi-451">注</span></h2><div class="section" id="converting-an-argument-sequence-to-a-string-on-windows"><h3><span class="yiyi-st" id="yiyi-452">17.5.8.1. </span><span class="yiyi-st" id="yiyi-453">将参数序列转换为Windows上的字符串</span></h3><p><span class="yiyi-st" id="yiyi-454">在 Windows 上,<em>args</em> 序列被转换为一个可以使用下面的规则(MS C 的运行时规则)解析的字符串:</span></p><ol class="arabic simple"><li><span class="yiyi-st" id="yiyi-455">参数通过空白符分隔,空白符可以是空格或者制表符。</span></li><li><span class="yiyi-st" id="yiyi-456">由双引号括起来的字符串将被解释为单个参数,而不考虑其中包含的空格。</span><span class="yiyi-st" id="yiyi-457">引用的字符串可以嵌入参数中。</span></li><li><span class="yiyi-st" id="yiyi-458">一个前面带有反斜线的双引号解释为一个双引号字面量。</span></li><li><span class="yiyi-st" id="yiyi-459">反斜线按字面量解释,除非它们后面紧跟着一个双引号。</span></li><li><span class="yiyi-st" id="yiyi-460">如果反斜杠紧跟在双引号之前,则每对反斜杠都被解释为字面值反斜杠。</span><span class="yiyi-st" id="yiyi-461">如果反斜杠的数量为奇数,则最后一个反斜杠转义为下一个双引号,如规则3所述。</span></li></ol><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-462">另可参阅</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-463"><a class="reference internal" href="shlex.html#module-shlex" title="shlex: Simple lexical analysis for Unix shell-like languages."><code class="xref py py-mod docutils literal"><span class="pre">shlex</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-464">提供解析和转义命令行的功能的模块。</span></dd></dl></div></div></div></div></div> |