在 Python 中,subprocess 模块提供了哪些方式来运行外部命令?请说明它们的主要区别和使用场景。
考察说明
考查对 Python subprocess 模块常用 API 及其适用场景的理解。
回答思路
- 【回答框架 1】subprocess 模块用于生成子进程并与其通信,替代旧的 os.system 和 os.popen。核心函数包括 run、call、check_call、check_output 和 Popen。
- 【回答框架 2】run 是推荐的高层接口,Python 3.5 引入,返回 CompletedProcess 对象,包含返回码和输出;call 只返回返回码,check_call 在非零退出时抛异常,check_output 直接返回标准输出。
- 【回答框架 3】Popen 是底层接口,提供更细粒度的控制,如实时读写标准输入输出、后台运行、设置环境变量等,适合复杂交互场景。
- 【回答框架 4】选择时优先使用 run,除非需要实时流式处理或复杂管道,才使用 Popen。所有函数都支持 shell 参数,但默认应设为 False 以避免 shell 注入风险。
- 【回答框架 5】执行外部命令时需注意编码问题,默认使用 locale 编码,可通过 text 或 encoding 参数指定。超时可通过 timeout 参数控制,超时后进程会被杀死并抛出 TimeoutExpired。
- 【关键点 1】run 是首选的高层 API,返回 CompletedProcess 对象。
- 【关键点 2】Popen 用于需要实时交互或精细控制的场景。
- 【关键点 3】默认应避免使用 shell=True 以防止命令注入。
- 【关键点 4】使用 timeout 参数防止命令挂起。
- 【关键点 5】通过 text 或 encoding 参数处理文本输出编码。
- 【易错点 1】误用 shell=True 导致安全风险。
- 【易错点 2】忽略 check 参数导致非零退出码未被捕获。
- 【易错点 3】未处理子进程的 stdout/stderr 可能导致管道阻塞。