如何在Python脚本中执行source命令加载ROS2 Galactic环境?
问题原因
两种写法失效的核心逻辑是操作系统的进程环境隔离机制:source是Shell内置命令,仅会修改执行该命令的当前Shell进程内的环境变量。os.system()、带shell=True参数的subprocess类调用,都会启动一个独立于Python主进程的临时子Shell:
- 子Shell内执行
source /opt/ros/galactic/setup.bash时,仅会修改这个临时子进程的环境变量 - 命令执行完毕后子Shell立刻退出,所有环境改动随进程销毁被清空
- 作为父进程的Python主进程环境不会被任何修改,因此环境加载不生效,该表现和Ubuntu 20.04、Python 3.8的版本没有关联。
解决方案
根据实际使用场景二选一即可:
场景1:需要Python主进程本身加载ROS2环境(比如后续要导入rclpy、调用ROS相关Python库)
直接解析setup.bash导出的环境变量,写入当前Python进程的环境变量表,参考代码:
import os import subprocess ros_setup_path = "/opt/ros/galactic/setup.bash" # 启动子Shell加载环境后导出全量环境变量 proc = subprocess.Popen( f"source {ros_setup_path} && env", shell=True, stdout=subprocess.PIPE, text=True ) # 逐行解析环境变量,写入当前Python进程的环境配置 for line in proc.stdout: line = line.strip() if not line: continue # 仅按第一个等号分割,兼容值内容中包含等号的情况 key, _, value = line.partition("=") os.environ[key] = value proc.wait() # 后续代码可正常使用ROS2环境,比如直接导入rclpy # import rclpy
场景2:仅需要在Python中调用依赖ROS2环境的外部Shell命令
不需要修改Python本身的运行环境,只需要把source操作和目标执行命令放到同一个子Shell内运行即可,参考代码:
import subprocess # 同一个子Shell内先加载ROS环境,再执行目标命令,示例为查询当前运行的ROS节点 subprocess.run( "source /opt/ros/galactic/setup.bash && ros2 node list", shell=True, check=True )
注意事项
- 如果同时使用Python虚拟环境(venv/conda),注意调整环境加载顺序,避免ROS自带依赖包和虚拟环境内的包版本冲突。
- 操作系统层面不支持子进程直接修改父进程的环境变量,不要尝试通过子Shell执行source的方式回传环境配置到Python主进程。
内容的提问来源于stack exchange,提问作者Abhinav Kumar
相关产品推荐
相关产品推荐

