【问题标题】:Subprocess fails to print esxcli namespace correctly子进程无法正确打印 esxcli 命名空间
【发布时间】:2014-06-11 20:53:38
【问题描述】:

当我从命令行执行 esxcli 时,会出现诸如

之类的命令
esxcli --server=222.222.222.222 --username=foo@user.local --password='bar' --vihost=111.111.111.111 network vswitch standard portgroup add -p vlan1 -v switch1

工作正常。然而,从子进程调用总是失败,因为它无法识别命名空间。这是因为它将命名空间和命令放在引号中,而不是直接添加。我当前来自子进程调用的代码是:

import settings
import subprocess

subprocess.call(["esxcli",
                 "--server="+ settings.vserver,
                 "--username="+ settings.user,
                 "--password=\'"+ settings.pwd + "\'",
                 "--vihost="+ settings.host,
                 "network vswitch standard portgroup add",
                 "-p "+ settings.newpgname,
                 "-v "+ settings.newpgswitch])

当我运行subprocess.list2cmdline 时,我得到:

esxcli --server=222.222.222.222 --username=foo@user.local --password='bar' --vihost=111.111.111.111 "network vswitch standard portgroup add" "-p vlan1" "-v switch1"

注意命名空间和它后面的参数都用引号引起来。

我发现的关于 subprocess 的大多数问题都与 shell=True 相关,而不是关于其他非连字符前缀的参数。

我怎样才能让子进程运行正确的命令,而不需要额外的引号?

【问题讨论】:

  • 我最终只使用了旧的 os.system 调用。
  • 要查看正确的参数列表应该是什么样子,请致电shlex.split(shell_command)

标签: python subprocess vmware vsphere


【解决方案1】:

对于您的代码,您是说可执行文件的第五个参数应该是字符串“network vswitch standard portgroup add”。为了在命令行上传递它,它必须被引用。相反,您应该将它们设为单独的参数,就像它们在命令行上一样。这同样适用于标志参数;可执行文件不需要单个参数 "-v switch1",而是需要两个参数 "-v""switch1"。因此你应该这样做:

subprocess.call(["esxcli",
                 "--server="+settings.vserver,
                 "--username="+settings.user,
                 "--password="+settings.pwd,
                 "--vihost="+settings.host,
                 "network","vswitch","standard","portgroup","add",
                 "-p",settings.newpgname,
                 "-v",settings.newpgswitch])

【讨论】:

  • 不正确。它应该是:一个命令行参数 一个列表项,即 OP 已经正确指定了 "network vswitch.." 参数。还有其他错误,例如,错误的引号,应该是:"--password", setting.pwd 而不是(没有引号)。
  • @J.F.Sebastian 我不确定我是否跟随。如果每个命令行参数应该有一个列表项,那么列表肯定应该包含五个元素"network","vswitch","standard","portgroup","add" 而不是一个"network vswitch standard portgroup add",对吧?我倾向于在"--password",setting.pwd 上同意你的观点(我相信它有效),但是因为 OP 说原始命令包括 --password='bar',这只是一个命令行参数,所以我保留了这种风格。
  • 我的错误,我查看了第二行(引号中的位置),而不是第一行。 bar 周围的引号应该被删除(就像 shell 一样),因为默认情况下 subprocess 不会启动 shell(您将错误的密码传递给命令)。
  • 澄清:将--password='bar' 直接传递给子进程是您的 错误(没有shell 可以去掉引号)。
  • 我同意。虽然 '--option=value' 是否等同于 '--option', 'value' 取决于程序(应该但并非总是如此)。
猜你喜欢
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多