subprocess 模块详解
subprocess 是 Python 中用于创建和管理子进程的标准库模块,它允许你启动新的应用程序、连接到它们的输入/输出/错误管道,并获取它们的返回码。
基本用法
1. run() 函数 (Python 3.5+ 推荐)
import subprocess
# 基本用法
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
# 参数说明
# args: 要执行的命令,列表形式
# capture_output: 是否捕获输出
# text/universal_newlines: 以文本形式返回输入输出
# check: 如果返回码非零则抛出 CalledProcessError
# timeout: 超时时间(秒)
# shell: 是否通过shell执行
2. call()、check_call()、check_output()
# call() - 执行命令并返回返回码
retcode = subprocess.call(['ls', '-l'])
# check_call() - 执行命令,如果返回码非零则抛出异常
subprocess.check_call(['ls', '-l'])
# check_output() - 执行命令并返回输出
output = subprocess.check_output(['ls', '-l'], text=True)
高级用法
1. Popen 类
Popen 类提供了更灵活的子进程控制:
# 基本用法
proc = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
# 参数说明
# stdin/stdout/stderr: 标准输入/输出/错误
# cwd: 设置工作目录
# env: 环境变量
# shell: 通过shell执行
# universal_newlines: 文本模式
2. 管道连接
# 管道连接多个命令
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'python'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # 允许p1收到SIGPIPE信号
output = p2.communicate()[0]
3. 交互式输入
proc = subprocess.Popen(['python'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
proc.stdin.write('print("Hello")\n')
proc.stdin.write('exit()\n')
output = proc.communicate()[0]
print(output)
常见用例
1. 执行shell命令
# 安全方式(推荐)
subprocess.run(['ls', '-l'])
# 使用shell=True(有安全风险,除非必要)
subprocess.run('ls -l | grep python', shell=True)
2. 捕获输出和错误
result = subprocess.run(['ls', 'nonexistent'],
capture_output=True,
text=True)
print("Return code:", result.returncode)
print("Output:", result.stdout)
print("Error:", result.stderr)
3. 超时处理
try:
subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
print("Command timed out")
4. 设置工作目录和环境变量
subprocess.run(['ls'], cwd='/tmp')
env = {'PATH': '/usr/local/bin'}
subprocess.run(['echo', '$PATH'], env=env, shell=True)
安全注意事项
-
避免使用shell=True:除非必要,否则不要使用shell=True,因为它有shell注入风险
-
参数传递:使用列表形式传递参数比字符串更安全
-
输入验证:对用户提供的输入进行严格验证
跨平台考虑
-
Windows和Unix-like系统的命令差异
-
路径分隔符的不同
-
环境变量的差异
2万+

被折叠的 条评论
为什么被折叠?



