How to use subprocess when multiple arguments contain spaces?

后端 未结 10 2155

I\'m working on a wrapper script that will exercise a vmware executable, allowing for the automation of virtual machine startup/shutdown/register/deregister actions. I\'m t

相关标签:
10条回答
  • 2021-01-07 18:25

    Here's what I don't like

    vmrun_cmd = r"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"
    

    You've got spaces in the name of the command itself -- which is baffling your shell. Hence the "'c:\Program' is not recognized as an internal or external command, operable program or batch file."

    Option 1 -- put your .BAT file somewhere else. Indeed, put all your VMWare somewhere else. Here's the rule: Do Not Use "Program Files" Directory For Anything. It's just wrong.

    Option 2 -- quote the vmrun_cmd value

    vmrun_cmd = r'"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"'
    
    0 讨论(0)
  • 2021-01-07 18:27

    In Python on MS Windows, the subprocess.Popen class uses the CreateProcess API to started the process. CreateProcess takes a string rather than something like an array of arguments. Python uses subprocess.list2cmdline to convert the list of args to a string for CreateProcess.

    If I were you, I'd see what subprocess.list2cmdline(args) returns (where args is the first argument of Popen). It would be interesting to see if it is putting quotes around the first argument.

    Of course, this explanation might not apply in a Cygwin environment.

    Having said all this, I don't have MS Windows.

    0 讨论(0)
  • 2021-01-07 18:32

    That was quite a hard problem for the last three ours....nothing stated so far did work, neither using r"" or Popen with a list and so on. What did work in the end was a combination of format string and r"". So my solution is this:

    subprocess.Popen("{0} -f {1}".format(pathToExe, r'"%s"' % pathToVideoFileOrDir))
    

    where both variables pathToExe and pathToVideoFileOrDir have whitespaces in their path. Using \" within the formatted string did not work and resulted in the same error that the first path is not detected any longer correctly.

    0 讨论(0)
  • 2021-01-07 18:33

    Possibly stupid suggestion, but perhaps try the following, to remove subprocess + spaces from the equation:

    import os
    from subprocess Popen, PIPE
    
    os.chdir(
        os.path.join("C:", "Program Files", "VMware", "VMware Server")
    )
    
    p = Popen(
        ["vmware-cmd.bat", target_vm, list_arg, list_arg2],
        stdout=PIPE
    ).communicate()[0]
    

    It might also be worth trying..

    p = Popen(
        [os.path.join("C:", "Program Files", "VMware", "VMware Server", "vmware-cmd.bat"), ...
    
    0 讨论(0)
  • 2021-01-07 18:40
    'c:\Program' is not recognized as an internal or external command,
    operable program or batch file.
    

    To get this message, you are either:

    1. Using shell=True:

      vmrun_cmd = r"c:\Program Files\VMware\VMware Server\vmware-cmd.bat"
      subprocess.Popen(vmrun_cmd, shell=True)
      
    2. Changing vmrun_cmd on other part of your code

    3. Getting this error from something inside vmware-cmd.bat

    Things to try:

    • Open a python prompt, run the following command:

      subprocess.Popen([r"c:\Program Files\VMware\VMware Server\vmware-cmd.bat"])
      

    If that works, then quoting issues are out of the question. If not, you've isolated the problem.

    0 讨论(0)
  • 2021-01-07 18:40

    I believe that list2cmdline(), which is doing the processing of your list args, splits any string arg on whitespace unless the string contains double quotes. So I would expect

    vmrun_cmd = r'"c:/Program Files/VMware/VMware Server/vmware-cmd.bat"'
    

    to be what you want.

    You'll also likely want to surround the other arguments (like target_vm) in double quotes on the assumption that they, too, each represent a distinct arg to present to the command line. Something like

    r'"%s"' % target_vm
    

    (for example) should suit.

    See the list2cmdline documentation

    D'A

    0 讨论(0)
提交回复
热议问题