subprocess模块替代os.system的正确方式
请说明为什么推荐使用subprocess模块替代os.system(),并演示subprocess.run()、subprocess.Popen()的核心用法和差异。
回答
我是大山
os.system(cmd)存在诸多问题:无法获取输出、安全风险(shell注入)、阻塞式调用、不支持超时。subprocess模块是推荐替代方案。
subprocess.run()(Python 3.5+,推荐方式):
import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True, timeout=10)
print(result.stdout) # 标准输出
print(result.stderr) # 错误输出
print(result.returncode) # 返回码,0表示成功
result.check_returncode() # 非0则抛出CalledProcessError
参数:shell=True执行shell命令(谨慎使用)、cwd设置工作目录、env设置环境变量。
subprocess.Popen()(更底层):
proc = subprocess.Popen(['ping', '127.0.0.1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate(timeout=5) # 等待子进程结束
Popen适合需要实时流式读取输出的场景,如持续处理子进程的输出流。
安全提示:默认不推荐shell=True,传递列表参数可避免shell注入。