subprocess执行系统命令简明用法
1. 基础用法(同步执行)
subprocess.run()
import subprocess
# 基本执行(输出直接打印到终端)
result = subprocess.run(["ls", "-l"])
# 捕获输出(推荐:安全+完整控制)
result = subprocess.run(
["ls", "-l"],
capture_output=True, # 捕获stdout和stderr
text=True # 输出转为字符串(默认字节流)
)
print(result.stdout) # 标准输出内容
print(result.returncode) # 命令返回码(0为成功)
快捷方法
# 直接获取输出字符串
output = subprocess.getoutput("ls -l")
# 获取字节流输出(非0返回码会抛异常)
output_bytes = subprocess.check_output(["ls", "-l"])
2. 错误处理
try:
# 若返回码非0,自动抛CalledProcessError
result = subprocess.run(
["invalid_cmd"],
check=True,
capture_output=True,
text=True
)
except subprocess.CalledProcessError as e:
print(f"错误输出: {e.stderr}")
print(f"返回码: {e.returncode}")
3. 超时控制
try:
result = subprocess.run(
["sleep", "10"],
timeout=5, # 5秒后终止命令
capture_output=True
)
except subprocess.TimeoutExpired:
print("命令执行超时!")
4. 管道操作(链式命令)
# 执行 ls | grep log
p1 = subprocess.Popen(["ls", "/var/log"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "syslog"], stdin=p1.stdout, stdout=subprocess.PIPE)
output = p2.communicate()[0] # 获取最终输出
print(output.decode())
5. 实用技巧
-
参数安全:优先用列表传参(如
["ls", "-l"]
),避免shell=True
注入风险 -
隐藏窗口(Windows):
startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.run("notepad", startupinfo=startupinfo)
-
实时输出:
process = subprocess.Popen(["ping", "google.com"], stdout=subprocess.PIPE) while True: line = process.stdout.readline() if not line: break print(line.decode().strip())
总结
- 首选
run()
:90%场景适用,同步+安全+易用 - 复杂需求用
Popen()
:异步、管道、实时交互 - 避免
shell=True
:除非必须执行Shell特性(如通配符*
)