Python subprocess模块详解:call、Popen与管道使用指南

清欢
清欢
发布时间:2026-10-13 | 6人浏览过
原创

本文深入解析Python中subprocess模块的核心用法,对比os.system的局限性,详细讲解subprocess.call()与Popen类的区别。通过示例演示如何安全处理标准输入输出、错误管道及返回值,并探讨shell=True的安全风险与正确实践,帮助开发者掌握进程管理的最佳方案。

subprocess模块概述与替代方案

过去在处理系统管理任务时,我常使用os.system(),认为这是执行Linux命令最简便的方法。然而,Python官方文档明确指出,应当采用subprocess模块来运行系统命令。该模块允许创建子进程,连接其输入/输出/错误管道,并获取返回值。subprocess模块旨在替代os.system、os.spawn*、os.popen*及popen2.*等过时模块和函数。接下来,我们将探讨subprocess提供的不同函数及其具体应用。

subprocess.call()函数详解

subprocess.call()

该函数用于执行由参数指定的命令。

你可以传递数组作为参数来运行命令,或者通过设置shell=True参数,以字符串形式传递命令。

需要注意的是,shell参数的默认值为False。

以下示例展示了如何使用subprocess.call()统计磁盘空间:


subprocess.call(['df', '-h'])

下面的例子将shell参数设置为True:


subprocess.call('du -hs $HOME', shell=True)

请注意,Python官方文档对shell=True参数提出了安全警告:


Invoking the system shell with shell=True can be a security hazard if combined
with untrusted input

输入输出与管道处理

接下来,我们探讨输入与输出的处理。

Input and Output

subprocess模块能够抑制输出,这在不需要关注标准输出时非常便捷。

它还提供了一种正确管理输入/输出的方式,使shell命令能够有条理地整合到Python脚本中。

Return Codes

通过subprocess.call()的返回值,你可以判断命令是否执行成功。每个进程退出时都会返回一个状态码,你可以基于此状态码编写相应的处理代码。

stdin, stdout and stderr

在使用subprocess时,一个关键细节是如何通过管道连接命令。

管道表明应当创建一个新的子管道。

默认设置为None,意味着不发生重定向。

标准错误可以指向标准输出,这意味着子进程的错误信息将被捕获并合并到标准输出中。

Popen类与communicate方法

subprocess.Popen()

subprocess模块中基本的进程创建和管理由Popen类处理。

subprocess.popen旨在替代os.popen。

我们来看一些实际例子,subprocess.Popen需要接收一个数组作为参数:


import subprocess
p = subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE)
print p.communicate()
>>>('hello world
', None)

注意,虽然可以使用shell=True,但官方并不推荐这种方式。

如果你确定只使用Popen和PIPE等有限函数,可以单独指定这些函数:


from subprocess import Popen, PIPE
p1 = Popen(["dmesg"], stdout=PIPE)
print p1.communicate()

Popen.communicate()

communicate()函数返回一个元组,包含标准输出和错误信息。

Popen.communicate()用于与进程通信:向标准输入发送数据,从标准输出和错误读取数据直到遇到结束符,并等待进程结束。

输入参数应是一个字符串,用于传递给子进程;如果没有数据,则应为None。

基本上,当你使用communicate()函数时,意味着你要执行命令。

实战:使用subprocess编写Ping程序

使用subprocess编写Ping程序

我们先询问用户地址,然后使用ping请求该地址。


# Import the module
import subprocess

# Ask the user for input
host = raw_input("Enter a host to ping: ")  

# Set up the echo command and direct the output to a pipe
p1 = subprocess.Popen(['ping', '-c 2', host], stdout=subprocess.PIPE)

# Run the command
output = p1.communicate()[0]

print output

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表