Search code examples
pythonlistsubprocessshlex

Why do I need 4 backslashes in a Python path?


When I'm using Python 3 to launch a program via subprocess.call(), why do I need 4 backslashes in paths?

This is my code:

cmd = 'C:\\\\Windows\\\\System32\\\\cmd.exe'

cmd = shlex.split(cmd)

subprocess.call(cmd)

When I examine the command line of the launched cmd.exe instance with Task Manager, it shows the path correctly with only one backslash separating each path.


Because of this, I need this on Windows to make the paths work:

if platform.platform().startswith('Windows'):
    cmd = cmd.replace(os.sep, os.sep + os.sep)

is there a more elegant solution?


Solution

  • Part of the problem is that you're using shlex, which implements escaping rules used by Unix-ish shells. But you're running on Windows, whose command shells use different rules. That accounts for one level of needing to double backslashes (i.e., to worm around something shlex does that you didn't need to begin with).

    That you're using a regular string instead of a raw string (r"...") accounts for the other level of needing to double backslashes, and 2*2 = 4. QED ;-)

    This works fine on Windows:

    cmd = subprocess.call(r"C:\Windows\System32\cmd.exe")
    

    By the way, read the docs for subprocess.Popen() carefully: the Windows CreateProcess() API call requires a string for an argument. When you pass a sequence instead, Python tries to turn that sequence into a string, via rules explained in the docs. When feasible, it's better - on Windows - to pass the string you want directly.