Сделать подпроцесс найти исполняемый файл git в Windows

import subprocess

proc = subprocess.Popen('git status')
print 'result: ', proc.communicate()

у меня есть git в моем системном пути, но когда я запускаю такой подпроцесс, я получаю:
WindowsError: [Error 2] The system cannot find the file specified

Как я могу получить подпроцесс, чтобы найти git в системном пути?

Python 2.6 в Windows XP.

3 ответов


проблема, которую вы видите здесь, заключается в том, что функция Windows API является CreateProcess, используемый подпроцессом под капотом, не разрешает автоматически другие исполняемые расширения, чем .exe. В Windows команда " git " действительно установлена как git.cmd. Поэтому вы должны изменить свой пример, чтобы явно вызвать git.cmd:

import subprocess

proc = subprocess.Popen('git.cmd status')
print 'result: ', proc.communicate()

причина git работает shell==True это то, что оболочка Windows автоматически разрешает git to git.cmd.

в конце концов, решите git.КМД себя:

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

ты имеешь в виду

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

первый аргумент subprocess.Popen принимает shlex.split-как список аргументов.

или:

proc = subprocess.Popen("git status", stdout=subprocess.PIPE, shell=True)

Это не рекомендуется, так как вы запускаете оболочку, а затем запускаете процесс в оболочке.

кроме того, вы должны использовать stdout=subprocess.PIPE для получения результата.


Я считаю, что вам нужно пройти env в Popen, что-то вроде:

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

должен сделать трюк.