我尝试使用 subprocess.Popen()
运行以下命令:
ros_version_retrieve = subprocess.Popen(["rosversion", "-d"], shell=False, stdout=subprocess.PIPE)
ros_version_retrieve.wait()
rosversion
是ROS的一部分,允许通过调用 rosversion <package>
来检索给定包的版本,或者通过调用 rosversion -d
来检索已安装ROS的版本 . 在第一种情况下,我将得到一个像 1.12.3
的字符串,在第二种情况下,我得到 kinetic
(因为那是我目前正在使用的版本) .
我从终端启动Eclipse,以便在IDE中也可以使用 PATH
和其他几个变量:
-
PYTHONPATH
是 /usr/local/lib/python2.7/dist-packages:/home/user/catkin_ws/devel/lib/python2.7/dist-packages:/opt/ros/kinetic/lib/python2.7/dist-packages:/usr/local/lib/python3.5/dist-packages/:/opt/OpenCV/python/3.4:/opt/OpenCV/python/2.7:/opt/ros/indigo/lib/python2.7/dist-packages -
PATH
是 /opt/Qts/5.9/bin:/opt/QtCreator-custom/bin:/usr/local/bin:/opt/MATLAB/R2012a/bin/:/home/user/bin:/home/user/catkin_ws/scripts:/opt/ros/kinetic/bin:/home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/Qts/5.9/bin:/snap/bin:/usr/lib/jvm/java-9-oracle/bin:/usr/lib/jvm/java-9-oracle/db/bin
我知道's quite untidy (I'刚刚了解了 virtualenv
)但它迄今为止没有任何问题 .
当我从PyDev(Eclipse Neon)内部运行第一行同样的代码时,我得到了
致命Python错误:Py_Initialize:无法获取语言环境编码文件“/usr/lib/python2.7/encodings/init.py”,第123行引发CodecRegistryError,\ ^语法错误:语法无效
我也尝试用特定的包调用 rosversion
subprocess.Popen(["rosversion", "roscpp"], shell=False, stdout=subprocess.PIPE)
但我得到了同样的错误 . 两个命令调用在我的终端中没有一个问题,并且当我在PyDev之外调用我的脚本时 .
我已经按照this问题寻找答案了 . 取消设置我的 PYTHONPATH
,然后在我的代码中手动设置它不是一个选项 . 我也很确定找到命令,因为我在我的代码中有多个其他位置,我称之为 rospack
基本上它提供的每个参数的组合,它工作得很好 . 从错误以及我的PyDev项目的设置我也确定正确的解释器被称为Python 2.7而不是3.4,我也在我的系统上 .
因为这似乎(至少在我的情况下)是一个PyDev问题而不是系统范围的问题,我正在寻找一个解决方案,我不必更改我的脚本只是为了能够在PyDev中运行它 . 如果我需要设置项目设置,请告诉我 .
UPDATE:
谢谢你的回答 . 但是弹出 PYTHONPATH
会导致 rosversion
失败,但这次是由于无法在内部导入 rospkg
(这是通过 PYTHONPATH
加载的ROS环境的一部分) . 我的代码中没有 import rospkg
,因为这违背了我正在做的目的 - 一个ROS的外部配置工具甚至可以设置它,如果我导入和使用属于它的模块是不可能的 .
我的 PYTHONHOME
实际上是空的 . 如果我只添加建议的编码部分,则会发生与之前相同的错误 - PyInitialize
, CodecRegistryError
等 .
再次 - 如果我从bash启动它,脚本可以正常工作 . 它只在我从PyDev运行时失败 .
2 回答
我认为问题在于你在配置中混合使用Python 2和Python 3路径 .
即:从你的
PYTHONPATH
你有:我认为为了安全起见,您应该创建所需的环境并将其传递给子进程调用,正确填充密钥:
PYTHONPATH
PYTHONHOME
PYTHONIOENCODING
PYTHONUNBUFFERED
有点像:
也许
PATH
和LANG
也可以添加到该列表中(不确定,它在很大程度上取决于您正在启动的内容以及您使用的程序将读取的变量) .我只是尝试了一些东西并且它有效 - 我的
Popen()
的命令列表看起来像这样:["python2.7", "/usr/local/bin/rosversion", "-d"]
并且它有效!由于访问GitHub时遇到问题,我实际上无法访问source code of rosversion,尽管我很盲目,不能通过查看
rospkg
失败导入的错误来得出结论 .与
rospack
不同rosversion
是一个Python脚本 . 虽然在bash shell中调用它不会导致问题,但似乎在子进程中运行它需要我实际调用该子进程内的Python解释器并传递绝对路径(我可以使用which rosversion
获得) .