无法使用POpen

时间:2017-08-17 21:00:06

标签: python arguments subprocess popen ros

我目前正在研究为ROS(机器人操作系统)创建通用配置工具。使用subprocess.POpen()Tkinter我正在创建treeview,如下所示:

enter image description here

由于整齐的方式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参数连接到命令本身,但都是徒劳的。

在我无用的尝试中,我发现了一些相当奇怪的东西。 listdepends实际上都是传递给rospack的参数。实际上,如果您只拨打rospack,则会收到错误消息,告知您拨打rospack help以查看可用的参数。

因此,我尝试拆分这些内容,并将["rospack", "list"]["rospack", "depends", "ros_package"]传递给两个POpen来电。令我惊讶的是我得到了

  

[rospack]错误:没有给出命令。试试'rospack help'[rospack]

     

[rospack]错误:没有给出命令。试试'rospack help'

至少对我来说这是一种相当奇怪的行为。

1 个答案:

答案 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'成为运行的命令,因此不存在,因此失败。