Python 中如何执行外部程序或系统命令?
Python 执行系统命令推荐 subprocess.run()(官方推荐,安全可靠),避免使用过时的 os.system()。本文介绍 subprocess.run 的用法、获取输出和安全注意事项。
推荐用 subprocess.run(['命令', '参数1', ...])——这是官方推荐的现代接口,参数以列表传递,能避免 shell 注入,还能方便地捕获输出和返回码。老的 os.system() 已不推荐。
基本用法
import subprocess
subprocess.run(['ls', '-la'])
列表第一个元素是程序名,其余是参数。
捕获输出与返回码
result = subprocess.run(['ls', '-la'], capture_output=True, text=True)
print(result.stdout) # 标准输出(字符串)
print(result.returncode) # 退出码,0 表示成功
capture_output=True:捕获 stdout 和 stderr;text=True:以字符串而非字节返回;check=True:命令失败(返回码非 0)时抛CalledProcessError。
为什么不推荐 os.system()
os.system('ls -la') # 输出直接打到终端,拿不到结果;只返回退出状态
缺点:无法捕获输出、参数拼接容易引入 shell 注入风险、官方文档明确建议用 subprocess 替代。
安全提示
不要用 shell=True 拼接用户输入:
# 危险!
subprocess.run(f'cat {user_input}', shell=True)
# 安全:参数列表传递,不经 shell 解释
subprocess.run(['cat', user_input])
常见问题(FAQ)
Q:命令执行很久会卡住吗?
A:run() 是阻塞的,可以加 timeout=秒数,超时抛 TimeoutExpired;需要异步并行用 subprocess.Popen。
Q:Windows 和 Linux 通用吗?
A:subprocess 本身跨平台,但命令名和参数因系统而异;shell=True 下 Windows 走 cmd,Linux 走 /bin/sh。
Q:如何执行带管道、重定向的命令?
A:管道建议在 Python 里串多个 subprocess(一个的输出接另一个的输入);重定向用 stdout=open('f', 'w')。实在需要 shell 特性才考虑 shell=True。