Make subprocess find git executable on Windows

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

How can I get subprocess to find git in the system path?

Python 2.6 on Windows XP.


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 :

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 .

Eventually, resolve git.cmd yourself:

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()

You mean

proc = subprocess.Popen(["git", "status"], stdout=subprocess.PIPE)

The first argument of subprocess.Popen takes a shlex.split -like list of arguments.

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.

Also, you should use stdout=subprocess.PIPE to retrieve the result.


I believe you need to pass env in to Popen, something like:

import subprocess, os
proc = subprocess.Popen('git status', env=os.environ, stdout=subprocess.PIPE)

Should do the trick.

链接地址: http://www.djcxy.com/p/50858.html

上一篇: “git checkout <filename>”和“git checkout”之间的区别

下一篇: 使子进程在Windows上找到git可执行文件