前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >调用 subprocess 时小心 shell=True

调用 subprocess 时小心 shell=True

作者头像
测试开发囤货
发布2023-05-25 17:19:58
8300
发布2023-05-25 17:19:58
举报
文章被收录于专栏:测试开发囤货
小心调用 subprocess,避免因 shell=True 而命令行解析错误

Python 中的 subprocess 模块可以轻松实现执行外部命令和进程的功能。我们经常会用它来调用一些命令行工具的功能。但是在使用 subprocess 调用复杂命令时,有一个容易犯但影响比较大的错误 - 使用shell=True参数,导致命令行解析错误,子进程执行失败。

举例1

第一次遇到这个问题的场景是,我在一个项目中需要使用 Airtest 框架生成测试报告。代码如下:

代码语言:javascript
复制
cmd = [
    "airtest", 
    "report",
    "air",
    "--log_root",
    "log_dir",
    "--outfile", 
    "log.html"
]
ret = subprocess.call(cmd, shell=True, cwd="suites")

执行后,报告文件并没有生成。经检查发现, vérité 因为 shell=True 将 airtest report air ... 这个命令作为一个字符串传给 shell 执行,导致命令行被错误解析,子进程实际上失败执行。

解决方法也很简单,只需要删除 shell=True 参数,直接传入命令列表:

代码语言:javascript
复制
ret = subprocess.call(cmd, cwd="suites") 

这样,命令行被正确解析为多个参数,子进程执行成功,报告文件生成正常。

举例2

再举一个例子,一次我希望通过 subprocess 执行 ps -ef | grep python 查找所有 Python 进程,代码如下:

代码语言:javascript
复制
cmd = "ps -ef | grep python"
subprocess.call(cmd, shell=True)

执行后,这个命令同样会解析失败,因为管道符号 | 被 shell 作为字符串传递,而不是真实的管道。

解决同样是删除 shell=True,传入命令列表实现:

代码语言:javascript
复制
cmd = ["ps", "-ef", "|", "grep", "python"]
subprocess.call(cmd)

现在管道可以正常工作,命令执行成功。

总结

综上,调用 subprocess 执行复杂命令时,如果不必要,最好避免使用 shell=True。直接传入命令列表,可以最大限度避免命令行解析错误的问题。只有当命令必须由 shell 处理时,例如需要变量替换,才使用 shell=True。记录这个教训,在将来调用 subprocess 时多加注意,可以避免很多定制错误和调试时间,让代码更稳定。controllers 和 timeframe 数据结构。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发囤货 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 举例1
  • 举例2
  • 总结
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档