Python subprocess.check_output(args) fails, while

2019-02-27 15:25发布

问题:

Some problems with python subprocess.check_output.

output = subprocess.check_output(args)

where my args is:

args = "C:\\DO\\bin\\Config.exe --ChCfg7 --LFE -b1152000 C:\\DO\\PCM\\1.wav C:\\DO\\PCM\\2.wav C:\\DO\\PCM\\3.wav C:\\DO\\PCM\\4.wav C:\\DO\\PCM\\5.wav C:\\DO\\PCM\6.wav --ModeBCast -oC:\\DO\\OUT\\outfile > C:\\DO\\OUT\\log.txt

This works when executed from standard windows command line, but doesn't work when executed via Python subprocess.check_output. In win cmd case there is output file produced and log.txt too, and python script produces out file with size 0, and no log.txt at all.

回答1:

output = subprocess.check_output(args,shell=True)

Run this with shell=True



回答2:

Use a list of args and redirect the output to a file:

import subprocess

args = ['C:/DO/bin/Config.exe', '--ChCfg7', '--LFE', '-b1152000', 'C:/DO/PCM/1.wav', 'C:/DO/PCM/2.wav', 'C:/DO/PCM/3.wav', 'C:/DO/PCM/4.wav', 'C:/DO/PCM/5.wav', 'C:/DO/PCM/6.wav', '--ModeBCast', '-oC:/DO/OUT/outfile']

with open("C:/DO/OUT/log.txt", "w") as f:
    subprocess.check_call(args, stdout=f)

You can use shell=Truebut for security reasons generally it is not a very good idea and the same can be quite easily achieved using the code above and simply redirecting the output to the file.



回答3:

> is a shell redirection operator. Either run the command in a shell or (better) as @Padraic Cunningham suggested emulate it in Python:

#!/usr/bin/env python
import subprocess

args = r"C:\DO\bin\Config.exe --ChCfg7 --LFE -b1152000".split()
args += [r'C:\DO\PCM\%d.wav' % i for i in range(1, 7)]
args += ["--ModeBCast", r"-oC:\DO\OUT\outfile"]    
with open(r"C:\DO\OUT\log.txt", "wb", 0) as output_file:
    subprocess.check_call(args, stdout=output_file)

The code uses raw string literals for Windows paths to avoid escaping backslashes.

There is usually no point to use shell=True on Windows unless you want to run a built-in command such as dir. If args is not constructed using input from an external source then security considerations do not apply. shell=True starts additional process (%COMSPEC%) and it changes how the executable is searched and it changes what characters should be escaped (what characters are metacharacters) — do not use shell=True unless necessary.