问题:Windows在subprocess.call()上找不到文件
我收到以下错误:
WindowsError: [Error 2] The system cannot find the file specified
我的代码是:
subprocess.call(["<<executable file found in PATH>>"])
Windows 7,64位。Python 3.x最新,稳定。
有任何想法吗?
谢谢,
I am getting the following error:
WindowsError: [Error 2] The system cannot find the file specified
My code is:
subprocess.call(["<<executable file found in PATH>>"])
Windows 7, 64 bit. Python 3.x latest, stable.
Any ideas?
Thanks,
回答 0
当命令是内置的shell时,请在调用中添加“ shell = True”。
例如,dir
您将输入:
import subprocess
subprocess.call('dir', shell=True)
引用文档:
在Windows上唯一需要指定shell = True的时间是将要执行的命令内置到shell中(例如dir或copy)。您不需要shell = True即可运行批处理文件或基于控制台的可执行文件。
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 need shell=True to run a batch file or console-based executable.
回答 1
在Windows上,我相信除非您通过subprocess
,PATH
否则shell=True
该模块不会进入,因为它CreateProcess()
在后台使用。但是,shell=True
如果传递的参数可能来自程序外部,则可能存在安全风险。为了subprocess
仍然能找到正确的可执行文件,你可以使用shutil.which
。假设您中的可执行文件PATH
名为frob
:
subprocess.call([shutil.which('frob'), arg1, arg2])
(这适用于Python 3.3及更高版本。)
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.)
回答 2
在Windows上,您必须通过cmd.exe进行调用。如Apalala所述,Windows命令不是作为单独的可执行文件在cmd.exe中实现的。
例如
subprocess.call(['cmd', '/c', 'dir'])
/ c告诉cmd运行以下命令
这比使用shell = True(允许shell注入)更安全。
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.
回答 3
如果您使用的是Powershell,则将在其中subprocess.call(['powershell','-command','dir'])
。Powershell支持大部分POSIX命令
If you are using powershell, then in it will be subprocess.call(['powershell','-command','dir'])
. Powershell supports a large portion of POSIX commands
回答 4
After much head scratching, I discovered that running a file that is located in C:\Windows\System32\ while running a 32bit version of python on a 64bit machine is a potential issue, due to Windows trying to out-smart the process, and redirect calls to C:\Windows\System32 to C:\Windows\SysWOW64.
I found an example of how to fix this here:
http://code.activestate.com/recipes/578035-disable-file-system-redirector/
回答 5
引用文档:
“在Python 3.5之前,这三个函数包含用于子过程的高级API。您现在可以在许多情况下使用run(),但是许多现有代码都调用了这些函数。”
因此:对于Python 3.5及更高版本,请使用subprocess.run而不是subprocess.call
To quote from the documentation:
“Prior to Python 3.5, these three functions comprised the high level API to subprocess. You can now use run() in many cases, but lots of existing code calls these functions.”
SO: instead of subprocess.call use subprocess.run for Python 3.5 and above
回答 6
在调用PHP时遇到了相同的问题。原因是PHP不在PATH中,所以找不到命令PHP。但是PowerShell发现它确实存在于当前位置,如果我信任此命令,建议将“ PHP”替换为“。\ PHP”。然后运行良好。
I met the same issue while I was calling a PHP. The reason is PHP isn’t in PATH so the command PHP was not found. But PowerShell found it does exist in the current location and it suggests replacing the ‘PHP’ by the ‘.\PHP’ if I trust this command. Then it runs well.