无法使用 POpen 将参数传递给子进程
Unable to pass argument to subprocess with POpen
我目前正在研究为 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>
需要的所有包出现在系统上以构建 and/or 运行)。对于 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] Error: no package given
和 return 值始终是一个空列表。我什至尝试将 ros_package
参数连接到命令本身,但都是徒劳的。
在我徒劳的尝试中,我发现了一些很奇怪的东西。 list
和 depends
实际上都是传递给 rospack
的参数。事实上,如果你只调用 rospack
你会得到一个错误提示你调用 rospack help
来查看可用的参数。
因此我尝试将这些东西分开并将 ["rospack", "list"]
和 ["rospack", "depends", "ros_package"]
传递给两个 POpen
调用。令我惊讶的是,我得到了
[rospack] Error: no command given. Try 'rospack help' [rospack]
[rospack] Error: no command given. Try 'rospack help'
这至少对我来说是一种相当奇怪的行为。
这是对如何 运行 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
重要部分(以下是文档中的相关引述):
If shell is True, it is recommended to pass args as a string rather
than as a sequence. ...
If args is a sequence, the first item
specifies the command string, and any additional items will be treated
as additional arguments to the shell itself.
所以当你传递 shell=True
并像 ['rospack', 'list']
一样传递它时,rospack
最终成为命令,而 list
成为 [=35= 的参数]shell,不是你想要的。
当 shell=False
并且你像 ['rospack depends', rosmodule]
一样传递它时,这使得字符串 'rospack depends'
成为 运行 的命令,它不存在因此失败。
我目前正在研究为 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>
需要的所有包出现在系统上以构建 and/or 运行)。对于 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] Error: no package given
和 return 值始终是一个空列表。我什至尝试将 ros_package
参数连接到命令本身,但都是徒劳的。
在我徒劳的尝试中,我发现了一些很奇怪的东西。 list
和 depends
实际上都是传递给 rospack
的参数。事实上,如果你只调用 rospack
你会得到一个错误提示你调用 rospack help
来查看可用的参数。
因此我尝试将这些东西分开并将 ["rospack", "list"]
和 ["rospack", "depends", "ros_package"]
传递给两个 POpen
调用。令我惊讶的是,我得到了
[rospack] Error: no command given. Try 'rospack help' [rospack]
[rospack] Error: no command given. Try 'rospack help'
这至少对我来说是一种相当奇怪的行为。
这是对如何 运行 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
重要部分(以下是文档中的相关引述):
If shell is True, it is recommended to pass args as a string rather than as a sequence. ...
If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.
所以当你传递 shell=True
并像 ['rospack', 'list']
一样传递它时,rospack
最终成为命令,而 list
成为 [=35= 的参数]shell,不是你想要的。
当 shell=False
并且你像 ['rospack depends', rosmodule]
一样传递它时,这使得字符串 'rospack depends'
成为 运行 的命令,它不存在因此失败。