我正在尝试使用我的命令行 git 客户端和 Python 的 I/O 重定向来自动化许多 git repos 上的一些常见操作。(是的,这是 hack-ish。我以后可能会回去使用 Python 库来执行此操作,但现在它似乎工作正常 :))
我希望能够捕获调用 git 的输出。隐藏输出看起来会更好,捕获它会让我记录它以防万一它有用。
我的问题是,当我运行“git clone”命令时,我只能得到第一行的输出。奇怪的是,带有“git status”的相同代码似乎工作得很好。
我在 Windows 7 上运行 Python 2.7,并且正在使用 cmd.exe 命令解释器。
到目前为止我的调查:
当我用“git clone”调用 subprocess.call() 时,它运行良好,我在控制台上看到了输出(这证实了 git 正在产生输出,即使我没有捕获它)。这段代码:
dir = "E:\\Work\\etc\\etc" os.chdir(dir) git_cmd = "git clone git@192.168.56.101:Mike_VonP/bit142_assign_2.git" #print "SUBPROCESS.CALL" + "="*20 #ret = subprocess.call(git_cmd.split(), shell=True)
将在控制台上生成此输出:
SUBPROCESS.CALL==================== Cloning into 'bit142_assign_2'... remote: Counting objects: 9, done. remote: Compressing objects: 100% (4/4), done. remote: Total 9 (delta 0), reused 0 (delta 0) Receiving objects: 100% (9/9), done. Checking connectivity... done.
如果我直接用 POpen 做同样的事情,我会在控制台上看到相同的输出(也没有被捕获)。这段代码:
# (the dir = , os.chdir, and git_cmd= lines are still executed here) print "SUBPROCESS.POPEN" + "="*20 p=subprocess.Popen(git_cmd.split(), shell=True) p.wait()
将产生这个(实际上相同的)输出:
SUBPROCESS.POPEN==================== Cloning into 'bit142_assign_2'... remote: Counting objects: 9, done. remote: Compressing objects: 100% (4/4), done. remote: Total 9 (delta 0), reused 0 (delta 0) Receiving objects: 100% (9/9), done. Checking connectivity... done.
(显然我在运行之间删除了克隆的 repo,否则我会收到“一切都是最新的”消息)
如果我使用communicate() 方法,我期望得到一个包含我在上面看到的所有输出的字符串。相反,我只看到这条线
Cloning into 'bit142_assign_2'...
。
这段代码:print "SUBPROCESS.POPEN, COMMUNICATE" + "="*20 p=subprocess.Popen(git_cmd.split(), shell=True,\ bufsize = 1,\ stderr=subprocess.PIPE,\ stdout=subprocess.PIPE) tuple = p.communicate() p.wait() print "StdOut:\n" + tuple[0] print "StdErr:\n" + tuple[1]
将产生这个输出:
SUBPROCESS.POPEN, COMMUNICATE==================== StdOut: StdErr: Cloning into 'bit142_assign_2'...
一方面,我重定向了输出(正如您从它不在输出中的事实中看到的那样),但我也只捕获了第一行。
我已经尝试了很多很多东西(调用check_output
而不是popen,使用带有subprocess.call的管道,使用带有subprocess.popen的管道,以及可能我忘记的其他东西)但没有任何效果 - 我只捕获第一行的输出。
有趣的是,完全相同的代码确实可以与 'git status' 一起正常工作。一旦 repo 被克隆,调用 git status 会产生三行输出(统称为“一切都是最新的”),第三个示例(POpen+communicate 代码)确实捕获了所有三行输出。
如果有人对我做错了什么有任何想法,或者对我可以尝试的任何事情有任何想法,以便更好地诊断这个问题,我将不胜感激。