我尝试使用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 /靛蓝/ LIB / python2.7 / DIST-封装 PATH
/opt/Qts/5.9/bin:/opt/QtCreator-custom/bin:/usr/local/bin:/opt/MATLAB/R2012a/bin /:/ home /用户/斌:/ home / user中/ catkin_ws /脚本中:/ opt / ROS /运动/斌:/ home / user中/斌:在/ 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 /分贝/ bin中 我知道它非常不整洁(我刚刚了解了virtualenv
)但它到目前为止没有任何问题。
当我从PyDev(Eclipse Neon)内部运行第一行同样的代码时,我得到了
致命Python错误:Py_Initialize:无法获取语言环境编码
文件&#34; /usr/lib/python2.7/encodings/ init .py&#34;,第123行 提出CodecRegistryError,\^ SyntaxError:语法无效
我也尝试使用特定的包
来调用rosversion
subprocess.Popen(["rosversion", "roscpp"], shell=False, stdout=subprocess.PIPE)
但我得到了同样的错误。这两个命令调用在我的终端中没有任何问题,并且当我在PyDev之外调用我的脚本时也是如此。
我已按照this问题寻找答案。取消设置我的PYTHONPATH
,然后在我的代码中手动设置它不是一个选项。我也非常确定找到命令,因为我的代码中有多个其他位置,我调用rospack
基本上它提供的每个参数的组合,它工作得很好。从我的PyDev项目的错误和设置中我也确定正确的解释器被称为Python 2.7而不是3.4,我也在我的系统上。
由于这似乎(至少在我的情况下)是一个PyDev问题,而不是系统范围的问题,我正在寻找一个解决方案,我不必改变我的脚本只是为了能够在PyDev中运行它。如果我需要设置项目设置,请告诉。
更新
感谢下面的答案。但是弹出PYTHONPATH
导致rosversion
失败,但这次是由于无法在内部导入rospkg
(这是通过PYTHONPATH
加载的ROS环境的一部分)。我的代码中没有任何地方import rospkg
,因为这违背了我正在做的事情的目的 - 一个甚至可以设置ROS的外部配置工具,如果我导入的话,这是不可能的并使用属于它的模块。
我的PYTHONHOME
实际上是空的。如果我只添加建议的编码部分,则会发生与以前相同的错误 - PyInitialize
,CodecRegistryError
等等。
再次 - 如果我从bash启动它,脚本可以正常运行。它只在我从PyDev运行时失败。
答案 0 :(得分:0)
我认为问题在于您在配置中混合了Python 2和Python 3路径。
即:来自您的PYTHONPATH
:
/usr/local/lib/python2.7/dist-packages
/home/user/catkin_ws/devel/lib/python2.7/dist-packages <-- py2
/opt/ros/kinetic/lib/python2.7/dist-packages
/usr/local/lib/python3.5/dist-packages/ <- py3
/opt/OpenCV/python/3.4:/opt/OpenCV/python/2.7
/opt/ros/indigo/lib/python2.7/dist-packages <-- py2
我认为为了安全起见,您应该创建所需的环境并将其传递给子进程调用,正确填写密钥:
东西:
env = os.environ.copy()
env.pop('PYTHONPATH', None)
env.pop('PYTHONHOME', None)
env['PYTHONIOENCODING'] = 'ascii'
env['PYTHONUNBUFFERED'] = '1'
subprocess.Popen(["rosversion", "-d"], env=env)
也许PATH
和LANG
也可以添加到该列表中(不确定,这很大程度上取决于您启动的内容以及您使用的程序将读取的变量)。< / p>
答案 1 :(得分:0)
我刚试了一些东西并且它有效 - 我的Popen()
的命令列表如下所示:["python2.7", "/usr/local/bin/rosversion", "-d"]
并且它有效!
由于访问GitHub时出现问题,我实际上无法访问source code of rosversion
,尽管我很盲目,不能通过查看rospkg
导入失败的错误来自己得出结论。
与rospack
不同rosversion
是一个Python脚本。虽然在bash shell中调用它不会导致问题,但似乎在子进程中运行它需要我实际调用该子进程内的Python解释器并传递绝对路径(我可以使用which rosversion
获取)。