Does Python's subprocess.Popen accept spaces in paths?

Question:

I have a simple Python script:

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

I’m executing it on Windows on the same python version 2.6.1, but on different VMs. One is Windows Server 2008 Enterprise, the second one it Windows Server Enterprise and I got error on only one of them.

The log from Windows Server Enterprise:

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

The log from Windows Server 2008 Enterprise:

Running command: C:Program FileMyProgramprogram.exe "parameters"
...

The error happens only for one environment. I know that the path should be escaped, but how is that possible that the subprocess.Popen could handle the path with space and without escaping?

Asked By: erkfel

||

Answers:

Paths with spaces need to be escaped. The easiest way to do this is to setup the command as a list, add shell=True and let python do the escaping for you:

import subprocess
cmd = [r"C:Program FileMyProgramprogram.exe", "param1", "param2"]
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,stdin=subprocess.PIPE, close_fds=close_fds)
Answered By: tdelaney

Consider this:

command = "C:Path argumentorpath"

How do you differentiate between an executable C:Path with an argument argumentorpath and a command path located at C:Path argumentor? If you pass an list instead of a string to Popen however, the intent is unambiguous:

command = ["C:Path argumentorpath"]
proc = Popen(command, ...)
Answered By: Joel Cornett

For anybody that stumbles upon this post looking for a solution to this, encapsulating the executable in quotes works on Windows and replacing ‘ ‘ with ‘ ‘ works in bash (Linux/MacOS) for Popen shell commands.

Here’s what worked for me:

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)
Answered By: Viktor Petrov

Here is what I found to work for windows :

Either of the below statements will open the specified file with the program specified :

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

Unfortunately, subprocess.run does not work with the iterable arguments. The following for me did not work :

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)
Answered By: J.Vo

An ugly work around, but a very effective one nevertheless
– Use python to create a batch file with your command
– Execute the batch file
– Delete the batch file

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

And then use something like this:

runThis('start "C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE" "' + Directory + '\' + FileName + '"')
Answered By: Menny Barzilay
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.