我目前正在研究为ROS(机器人操作系统)创建通用配置工具。使用subprocess.POpen()
和Tkinter
我正在创建treeview
,如下所示:
由于整齐的方式rospack list
(列出系统上安装的所有软件包,包括开发人员创建自己的工作区内的软件包),前两列的创建非常简单包)工作:
ros_packages_install_retrieve = subprocess.Popen(["rospack list"], shell=True, stdout=subprocess.PIPE)
ros_packages_installed = []
for ros_package in ros_packages_install_retrieve.stdout.readlines():
ros_package_adapted = ros_package.split(" ")
ros_package_adapted[1] = ros_package_adapted[1][:-1]
ros_packages_installed.append(ros_package_adapted)
需要列是棘手的,因为调用rospack depends <package>
时出现问题(列出(如果有的话)<package>
需要在系统中出现的所有包为了建立和/或运行)。对于ros_packages_installed
内的每个包,我调用以下函数:
def get_deps(ros_package):
ros_package_deps_retrieve = subprocess.Popen(["rospack", "depends", ros_package], shell=True, stdout=subprocess.PIPE)
ros_package_deps = []
for ros_package_dep in ros_package_deps_retrieve.stdout.readlines():
ros_package_dep = ros_package_dep.split("\n")
ros_package_dep = ros_package_dep[:-1]
ros_package_deps.append(ros_package_dep)
return ros_package_deps
问题在于我正在
[rospack]错误:没有给出包
并且返回值始终为空列表。我甚至尝试将ros_package
参数连接到命令本身,但都是徒劳的。
在我无用的尝试中,我发现了一些相当奇怪的东西。 list
和depends
实际上都是传递给rospack
的参数。实际上,如果您只拨打rospack
,则会收到错误消息,告知您拨打rospack help
以查看可用的参数。
因此,我尝试拆分这些内容,并将["rospack", "list"]
和["rospack", "depends", "ros_package"]
传递给两个POpen
来电。令我惊讶的是我得到了
[rospack]错误:没有给出命令。试试'rospack help'[rospack]
[rospack]错误:没有给出命令。试试'rospack help'
至少对我来说这是一种相当奇怪的行为。
答案 0 :(得分:3)
这是如何运行Popen的混乱。您应该使用shell=True
传递一个字符串:
ros_package_deps_retrieve = subprocess.Popen("rospack depends %s"rospack, shell=True, stdout=subprocess.PIPE)
或将其作为完全独立的列表传递,并使用shell=False
(默认情况下,无需指定):
ros_package_deps_retrieve = subprocess.Popen(["rospack", "depends", rospack], stdout=subprocess.PIPE)
请参阅此处的文档: https://docs.python.org/2/library/subprocess.html#popen-constructor
重要文章(以下是文档的相关引用):
如果shell为True,建议将args作为字符串传递 而不是一个序列。 ......
如果args是一个序列,那么第一个项目 指定命令字符串,并将处理任何其他项 作为shell本身的附加参数。
因此,当您传递shell=True
并像['rospack', 'list']
一样传递时,rospack
最终成为命令,list
成为 shell的参数,而不是你想要的。
当shell=False
和['rospack depends', rosmodule]
一样传递时,会使字符串'rospack depends'
成为运行的命令,因此不存在,因此失败。