在 Python 中使用子流程时出现回溯错误

Traceback error when using subprocess in Python

尝试使用 subprocess.check_output 时,我不断收到此回溯错误:

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    subprocess.check_output(["echo", "Hello World!"])
  File "C:\Python27\lib\subprocess.py", line 537, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "C:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

这甚至在我尝试时发生:

>>>subprocess.check_output(["echo", "Hello World!"])

这恰好是文档中的示例。

由于 ECHO 内置于 Windows cmd shell,您不能像调用可执行文件(或直接在 Linux 上调用它)。

即这应该适用于您的系统:

import subprocess
subprocess.check_output(['notepad'])

因为notepad.exe是一个可执行文件。但在 Windows 中,echo 只能从 shell 提示符中调用,因此使其工作的捷径是使用 shell=True。为了对您的代码保持信心,我必须写

subprocess.check_output(['echo', 'hello world'], shell=True) # Still not perfect

(这个,按照subprocess.py第924行的条件将args扩展成整行'C:\Windows\system32\cmd.exe /c "echo "hello world""',从而调用cmdshell并使用 shell 的 echo 命令)

但是,正如@J.F.Sebastian 友善地指出的那样,for portability a string, and not a list, should be used to pass arguments when using shell=True(查看有关 SO 的问题的链接)。因此,在您的情况下调用 subprocess.check_output 的最佳方式是:

subprocess.check_output('echo "hello world"', shell=True)

args 字符串又是正确的,'C:\Windows\system32\cmd.exe /c "echo "hello world""' 并且您的代码更易于移植。

docs 说:

"On Windows with shell=True, the COMSPEC environment variable specifies the default shell. The only time you need to specify shell=True on Windows is when the command you wish to execute is built into the shell (e.g. dir or copy). You do not need shell=True to run a batch file or console-based executable.

Warning: Passing shell=True can be a security hazard if combined with untrusted input. See the warning under Frequently Used Arguments for details. "