Does Python's subprocess.Popen accept spaces in paths?
Solution 1
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 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)
Solution 2
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)
Solution 3
Consider this:
command = "C:\Path argument\or\path"
How do you differentiate between an executable C:\Path with an argument argument\or\path and a command path located at C:\Path\ argument\or? If you pass an list instead of a string to Popen however, the intent is unambiguous:
command = ["C:\Path argument\or\path"]
proc = Popen(command, ...)
Related videos on Youtube
erkfel
Updated on March 26, 2020Comments
-
erkfel over 2 years
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 File\MyProgram\program.exe "parameters" Error: 'C:\\Program' is not recognized as an internal or external commandThe log from Windows Server 2008 Enterprise:
Running command: C:\Program File\MyProgram\program.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.Popencould handle the path with space and without escaping? -
erkfel over 8 yearsThanks for the reply, but that is not the answer to my question. My question is - why the same piece of code works differently on the same version of Python on almost the same Windows and how does it possible that subprocess.Popen could handle the non escaped path with spaces. It should be escaped, but it is not and this code works, I'm wondering why.
-
erkfel over 8 yearsJoel, thanks for the reply, but this is not the answer to the question, please see my comment to @tdelaney
-
Alexander Tronchin-James about 7 yearsUse of
shell=Trueis buggy (stderr causes hangs) and insecure, so not recommended. -
tdelaney about 7 years@AlexanderTronchin-James - buggy? If shell=True causes hangs, this is the first I've heard about it. shell=True does run the risk of command injection so its use is not advised everywhere but it is reasonably used in many cases. A build system for example. -
Elad Weiss almost 4 yearsThis is a working answer. The r"" solution in the answer above does not work if my command is taken from a variable. -
fdermishin almost 2 yearsYou need to callcmd.replace(' ', '\\ ')(with double backslash)