Python subprocess执行多命令失败:终端可行代码中报错排查
问题分析与解决方案
核心原因
你的命令在终端能正常运行,但subprocess.Popen执行失败,根源在于:
- 终端默认使用
bash,而subprocess.Popen(shell=True)默认调用/bin/sh(POSIX标准shell) export.sh中使用了bash专属的[[语法,sh不支持该扩展,因此报错[[: not found- 脚本执行失败导致后续
esptool.py运行所需的环境变量未正确加载,进而引发相关运行问题
解决方案
方案1:指定用bash执行命令
直接让subprocess调用bash解析命令串,确保export.sh的语法能被正确识别:
str1 = os.path.join(install_path, "components", "esptool_py", "esptool", "esptool.py") cmd1 = f"cd {install_path}; . ./export.sh; python3 {str1} flash_id" # 指定bash执行并捕获错误输出 cmd = subprocess.Popen( ["bash", "-c", cmd1], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) out, err = cmd.communicate() out_str = out.decode("utf-8") err_str = err.decode("utf-8") print(out_str) print(err_str)
方案2:用cwd参数指定工作目录(更安全)
避免在命令中拼接cd,直接通过cwd参数设置子进程的工作目录,同时指定bash执行:
str1 = os.path.join(install_path, "components", "esptool_py", "esptool", "esptool.py") # 去掉cd命令,直接在目标目录下执行操作 cmd_content = f". ./export.sh; python3 {str1} flash_id" cmd = subprocess.Popen( ["bash", "-c", cmd_content], cwd=install_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) out, err = cmd.communicate() out_str = out.decode("utf-8") err_str = err.decode("utf-8") print(out_str) print(err_str)
补充说明
- 必须添加
stderr=subprocess.PIPE,才能捕获完整的错误信息,方便排查问题 - 如果
install_path包含空格,方案2的cwd参数会自动处理,比在命令串中拼接cd更安全 export.sh的作用是配置ESP-IDF的环境变量,只有用bash正确执行它,后续的esptool.py才能正常运行
内容的提问来源于stack exchange,提问作者Pinkurauchin
相关产品推荐
相关产品推荐

