如何在多个参数包含空格时使用subprocess?
我正在写一个脚本,这个脚本可以控制vmware的程序,帮助自动化虚拟机的启动、关闭、注册和注销操作。我想用subprocess这个工具来调用这个程序,但发现程序路径和参数中的空格没有被正确处理。下面是一些代码片段:
vmrun_cmd = r"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"
def vm_start(target_vm):
list_arg = "start"
list_arg2 = "hard"
if vm_list(target_vm):
p = Popen([vmrun_cmd, target_vm, list_arg, list_arg2], stdout=PIPE).communicate()[0]
print p
else:
vm_register(target_vm)
vm_start(target_vm)
def vm_list2(target_vm):
list_arg = "-l"
p = Popen([vmrun_cmd, list_arg], stdout=PIPE).communicate()[0]
for line in p.split('\n'):
print line
当我调用vm_list2这个函数时,得到的输出是:
$ ./vmware_control.py --list
C:\Virtual Machines\QAW2K3Server\Windows Server 2003 Standard Edition.vmx
C:\Virtual Machines\ubunturouter\Ubuntu.vmx
C:\Virtual Machines\vacc\vacc.vmx
C:\Virtual Machines\EdgeAS-4.4.x\Other Linux 2.4.x kernel.vmx
C:\Virtual Machines\UbuntuServer1\Ubuntu.vmx
C:\Virtual Machines\Other Linux 2.4.x kernel\Other Linux 2.4.x kernel.vmx
C:\Virtual Machines\QAClient\Windows XP Professional.vmx
当我调用vm_start这个函数时,它需要一个虚拟机路径的参数,结果输出是:
$ ./vmware_control.py --start "C:\Virtual Machines\ubunturouter\Ubuntu.vmx"
'c:\Program' is not recognized as an internal or external command,
operable program or batch file.
看起来,第二个参数中有空格的存在,影响了subprocess对第一个参数的理解。有没有什么建议可以解决这个问题呢?
python2.5.2/cygwin/winxp
10 个回答
4
‘c:\Program’ 这个路径没有被识别为内部或外部命令,也不是可操作的程序或批处理文件。
出现这个提示的原因可能有:
你在使用
shell=True
:vmrun_cmd = r"c:\Program Files\VMware\VMware Server\vmware-cmd.bat" subprocess.Popen(vmrun_cmd, shell=True)
你在代码的其他地方修改了 vmrun_cmd
这个错误是从 vmware-cmd.bat 文件里面产生的
可以尝试以下方法:
打开一个 Python 提示符,运行以下命令:
subprocess.Popen([r"c:\Program Files\VMware\VMware Server\vmware-cmd.bat"])
如果这个命令能成功运行,那就说明引号的问题可以排除了。如果不行,那你就找到了问题所在。
5
我认为 list2cmdline() 这个函数在处理你的列表参数时,会根据空格来分割字符串参数,除非这个字符串里面有双引号。所以我预计
vmrun_cmd = r'"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"'
就是你想要的结果。
你可能还想把其他参数(比如 target_vm
)用双引号括起来,因为它们也代表了要传给命令行的不同参数。像这样的格式
r'"%s"' % target_vm
(例如)应该就合适了。
你可以查看 list2cmdline 的文档 来了解更多信息。
8
如果你的路径中有空格,我发现最简单的方法是这样处理。
subprocess.call('""' + path + '""')
我也不太清楚为什么需要用两个双引号,但这样做就是有效的。