Reputation: 8149
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.
Upvotes: 13
Views: 8210
Reputation: 1326782
Note that in 2020, with With Git 2.28 (Q3 2020), Python 2.6 or older is no longer supported.
See commit 45a87a8 (07 Jun 2020) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit 6361eb7, 18 Jun 2020)
CodingGuidelines
: specify Python 2.7 is the oldest versionSigned-off-by: Denton Liu
In 0b4396f068 ("
git-p4
: make python2.7 the oldest supported version", 2019-12-13, Git v2.27.0-rc0 -- merge listed in batch #1), git-p4 was updated to only support 2.7 and newer. Since Python 2.6 is pretty much ancient history, update CodingGuidelines to show that 2.7 is the oldest version supported.
Upvotes: 0
Reputation: 68067
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
.
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()
Upvotes: 12
Reputation:
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.
Upvotes: 0
Reputation: 4336
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.
Upvotes: -2