2

When trying to use subprocess.check_output, I keep getting this traceback error:

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

This even happens when I try:

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

That happens to be the example in the documentation.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
user3806019
  • 45
  • 2
  • 9

1 Answers1

3

Since ECHO is built into the Windows cmd shell, you can't call it from Python as directly as you would call an executable (or as directly as you would call it on Linux).

i.e. this should work in your system:

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

because notepad.exe is an executable. But in Windows, echo can only be called from inside a shell prompt, so the short way to make it work is to use shell=True. To keep faith to your code, I would have to write

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

(this, following the conditional on line 924 of subprocess.py will expand args into the full line 'C:\\Windows\\system32\\cmd.exe /c "echo "hello world""', thus calling the cmd shell and using the shell's echo command)

But, as @J.F.Sebastian kindly pointed out, for portability a string, and not a list, should be used to pass arguments when using shell=True (check the links to questions on SO there). So the best way to call subprocess.check_output in your case is:

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

The args string is again the correct one, 'C:\\Windows\\system32\\cmd.exe /c "echo "hello world""' and your code is more portable.

The docs say:

"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. "

Roberto
  • 2,696
  • 18
  • 31
  • Aaaand it's a [duplicate question](http://stackoverflow.com/questions/10933354/python-why-does-calling-echo-with-subprocess-return-windowserror-2). :/ Problem is that I could only find it when I googled for "echo is not a program" + subprocess – Roberto Jan 27 '15 at 01:49
  • 2
    please, [don't use `shell=True` and a list argument together (for portability)](http://bugs.python.org/issue21347), call `check_output('echo "hello world"', shell=True)` instead. – jfs Jan 27 '15 at 06:50