【问题标题】:Unable to pass argument to subprocess with POpen无法使用 POpen 将参数传递给子进程
【发布时间】:2018-01-26 10:41:31
【问题描述】:

我目前正在研究为 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)

Requires 列是一个棘手的列,因为调用 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 帮助”

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

【问题讨论】:

    标签: python arguments subprocess popen ros


    【解决方案1】:

    这是一个关于如何运行 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' 成为要运行的命令,该命令不存在,因此会失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      • 2016-10-27
      • 2023-03-03
      相关资源
      最近更新 更多