Felix
Felix

Reputation: 2668

Running a batch file with subprocess

I'd like to execute a simple batch file using Python. But I'm getting some error back from the process saying the file, directory or disc name is not right. I guess the best way to start is to show the code:

import subprocess as sp
from pathlib import Path

file = Path(r'C:\Program Files (x86)\test.bat')

p = sp.Popen(['"' + str(file) + '"'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE,
             shell=True, universal_newlines=True)
outs, errs = p.communicate('', timeout=5)
print(outs, '\n-----\n', errs)

I extended this with appending to system path and changing the working directory:

import os
import sys

sys.path.append(file.parent)
os.chdir(file.parent)

The batch file contains just a few echo commands for debugging. So I'd expect the code above to print the contents of the echoes. I've verified that I'm able to call it inside a command prompt from any folder. Previously I was getting some file permission error (WinError 5), so that might be related especially as the file is in Program Files. This error was not from the process, but Python itself.

I also tried it with an executable, and a similar error was raised: WinError 2: the system cannot find the file specified. Any idea where I'm stumbling?


Attempts

Upvotes: 0

Views: 3380

Answers (1)

Eryk Sun
Eryk Sun

Reputation: 34270

Use a command-line string instead of an args list when passing shell=True or when running a batch script with the default shell=False.

On Windows, Popen processes an args list into a command line that's compatible with VC++ argument parsing. But cmd.exe don't use VC++ argument parsing rules, and even for an executable that does use VC++ rules (e.g. python.exe), the extra quotes you're adding (i.e. '"' + str(file) + '"') get backslash-escaped as literal quotation marks in the command line.

Upvotes: 3

Related Questions