是python subprocess.Popen接受路径中的空格吗?

时间:2014-09-03 23:31:53

标签: python createprocess

我有一个简单的Python脚本:

log("Running command: " + str(cmd))
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=close_fds)

我在Windows上在同一个python版本2.6.1上执行它,但是在不同的VM上。一个是Windows Server 2008 Enterprise,第二个是Windows Server Enterprise,我在其中一个 时出错。

Windows Server Enterprise中的日志:

Running command: C:\Program File\MyProgram\program.exe "parameters"
Error: 'C:\\Program' is not recognized as an internal or external command

Windows Server 2008 Enterprise中的日志:

Running command: C:\Program File\MyProgram\program.exe "parameters"
...

错误仅发生在一个环境中。我知道路径应该被转义,但subprocess.Popen如何可以处理空间路径并且没有逃逸?

5 个答案:

答案 0 :(得分:3)

需要转义带空格的路径。最简单的方法是将命令设置为列表,添加shell = True并让python为您执行转义:

import subprocess
cmd = [r"C:\Program File\MyProgram\program.exe", "param1", "param2"]
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,stdin=subprocess.PIPE, close_fds=close_fds)

答案 1 :(得分:2)

考虑一下:

command = "C:\Path argument\or\path"

如何区分带有参数C:\Path的可执行文件argument\or\path和位于path的命令C:\Path\ argument\or?但是,如果将列表而不是字符串传递给Popen,则意图是明确的:

command = ["C:\Path argument\or\path"]
proc = Popen(command, ...)

答案 2 :(得分:0)

对于偶然发现本文的人,可以在Windows上将可执行文件封装在引号中,并在bash(Linux / MacOS)中将''替换为'\',以用于Popen shell命令。

这对我有用:

from subprocess import Popen
cmd = '/path/to/some executable with spaces'
# Execute in Windows shell:
Popen(r'"{}"'.format(cmd), shell=True)
# Execute in bash shell:
Popen(cmd.replace(' ', '\ '), shell=True)

答案 3 :(得分:0)

这是我发现可用于Windows的内容:

以下任何一条语句都将使用指定的程序打开指定的文件:

subprocess.run('start EXCEL.exe "%s"' %cmd_path, shell=True)
os.system('start EXCEL.exe "%s"' %cmd_path)

不幸的是,subprocess.run不适用于可迭代的参数。以下对我来说无效:

subprocess.call(['start','EXCEL.EXE', f'"%s"'%save_path])
subprocess.run(['start','EXCEL.EXE', f"%s"%save_path])
os.system('start EXCEL.EXE ' + f"%s"%save_path)

答案 4 :(得分:0)

一个丑陋的解决方法,但是却非常有效 -使用python通过命令创建批处理文件 -执行批处理文件 -删除批处理文件

def runThis(command):
    tempBatch = open(r'c:\temp\TemporaryBatchFile.bat', 'w')
    tempBatch.write(command)
    tempBatch.close()
    subprocess.call(r'c:\temp\TemporaryBatchFile.bat')

然后使用类似这样的内容:

runThis('start "C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE" "' + Directory + '\\' + FileName + '"')