使子进程在 Windows 上找到 git 可执行文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4965175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make subprocess find git executable on Windows
提问by Jesse Aldridge
import subprocess
proc = subprocess.Popen('git status')
print 'result: ', proc.communicate()
I have git in my system path, but when I run subprocess like this I get:WindowsError: [Error 2] The system cannot find the file specified
我的系统路径中有 git,但是当我像这样运行子进程时,我得到:WindowsError: [Error 2] The system cannot find the file specified
How can I get subprocess to find git in the system path?
如何让子进程在系统路径中找到 git?
Python 2.6 on Windows XP.
Windows XP 上的 Python 2.6。
采纳答案by aknuds1
The problem you see here is that the Windows API function CreateProcess, used by subprocess under the hood, doesn't auto-resolve other executable extensions than .exe
. On Windows, the 'git' command is really installed as git.cmd
. Therefore, you should modify your example to explicitly invoke git.cmd
:
您在此处看到的问题是 Windows API 函数CreateProcess由子进程在幕后使用,不会自动解析除.exe
. 在 Windows 上,'git' 命令实际上安装为git.cmd
. 因此,您应该修改您的示例以显式调用git.cmd
:
import subprocess
proc = subprocess.Popen('git.cmd status')
print 'result: ', proc.communicate()
The reason git
works when shell==True
is that the Windows shell auto-resolves git
to git.cmd
.
究其原因git
,当工作shell==True
是,Windows外壳程序自动做出决议git
来git.cmd
。
Eventually, resolve git.cmd yourself:
最后,自己解决 git.cmd :
import subprocess
import os.path
def resolve_path(executable):
if os.path.sep in executable:
raise ValueError("Invalid filename: %s" % executable)
path = os.environ.get("PATH", "").split(os.pathsep)
# PATHEXT tells us which extensions an executable may have
path_exts = os.environ.get("PATHEXT", ".exe;.bat;.cmd").split(";")
has_ext = os.path.splitext(executable)[1] in path_exts
if not has_ext:
exts = path_exts
else:
# Don't try to append any extensions
exts = [""]
for d in path:
try:
for ext in exts:
exepath = os.path.join(d, executable + ext)
if os.access(exepath, os.X_OK):
return exepath
except OSError:
pass
return None
git = resolve_path("git")
proc = subprocess.Popen('{0} status'.format(git))
print 'result: ', proc.communicate()
回答by aknuds1
You mean
你的意思是
proc = subprocess.Popen(["git", "status"], stdout=subprocess.PIPE)
The first argument of subprocess.Popen
takes a shlex.split
-like list of arguments.
的第一个参数subprocess.Popen
采用类似参数shlex.split
列表。
or:
或者:
proc = subprocess.Popen("git status", stdout=subprocess.PIPE, shell=True)
This is not recommended, as you are launching a shell then launching a process in the shell.
不建议这样做,因为您要启动 shell,然后在 shell 中启动进程。
Also, you should use stdout=subprocess.PIPE
to retrieve the result.
此外,您应该使用stdout=subprocess.PIPE
检索结果。
回答by jdd
I believe you need to pass env
in to Popen, something like:
我相信您需要传入env
Popen,例如:
import subprocess, os
proc = subprocess.Popen('git status', env=os.environ, stdout=subprocess.PIPE)
Should do the trick.
应该做的伎俩。