Windows can't find the file on subprocess.call()
Solution 1:
When the command is a shell built-in, add a shell=True
to the call.
E.g. for dir
you would type:
import subprocess
subprocess.call('dir', shell=True)
To quote from the documentation:
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 needshell=True
to run a batch file or console-based executable.
Solution 2:
On Windows, I believe the subprocess
module doesn't look in the PATH
unless you pass shell=True
because it use CreateProcess()
behind the scenes. However, shell=True
can be a security risk if you're passing arguments that may come from outside your program. To make subprocess
nonetheless able to find the correct executable, you can use shutil.which
. Suppose the executable in your PATH
is named frob
:
subprocess.call([shutil.which('frob'), arg1, arg2])
(This works on Python 3.3 and above.)
Solution 3:
On Windows you have to call through cmd.exe. As Apalala mentioned, Windows commands are implemented in cmd.exe not as separate executables.
e.g.
subprocess.call(['cmd', '/c', 'dir'])
/c tells cmd to run the follow command
This is safer than using shell=True, which allows shell injections.
Solution 4:
If you are using powershell, then in it will be subprocess.call(['powershell','-command','dir'])
. Powershell supports a large portion of POSIX commands