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

22,877

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, ...)
Share:
22,877

Related videos on Youtube

Author by

erkfel

Updated on March 26, 2020

Comments

  • 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 command
    

    The 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.Popen could handle the path with space and without escaping?

  • erkfel over 8 years
    Thanks 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 years
    Joel, thanks for the reply, but this is not the answer to the question, please see my comment to @tdelaney
  • Alexander Tronchin-James about 7 years
    Use of shell=True is buggy (stderr causes hangs) and insecure, so not recommended.
  • tdelaney
    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
    Elad Weiss almost 4 years
    This is a working answer. The r"" solution in the answer above does not work if my command is taken from a variable.
  • fdermishin
    fdermishin almost 2 years
    You need to call cmd.replace(' ', '\\ ') (with double backslash)

Related