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

时间:2015-01-27 00:12:58

标签: python windows subprocess

尝试使用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!"])

这恰好是文档中的例子。

1 个答案:

答案 0 :(得分:3)

由于ECHO内置于Windows cmd shell中,因此无法像调用可执行文件那样直接从Python调用它(或者直接在Linux上调用它)。

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

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

因为notepad.exe是可执行文件。但是在Windows中,只能在shell提示符内调用echo,因此使其工作的简短方法是使用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""',从而调用cmd shell并使用shell echo 1}}命令)

但是,正如@ 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说:

  

“在具有shell=True的Windows上,COMSPEC环境变量   指定默认shell。您唯一需要指定的时间   Windows上的shell=True是构建您要执行的命令的时间   进入shell(例如 dir 复制)。您不需要shell=True来运行   批处理文件或基于控制台的可执行文件。

     

警告:如果与不信任相结合,传递shell=True可能会造成安全隐患   输入。有关详细信息,请参阅 Frequently Used Arguments 下的警告。 “