【发布时间】:2017-01-26 15:05:28
【问题描述】:
我正在尝试使用我的命令行 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 代码)确实捕获了所有三行输出。
如果有人对我做错了什么有任何想法,或者对我可以尝试的任何事情有任何想法,以便更好地诊断这个问题,我将不胜感激。
【问题讨论】:
-
关于第三个示例的有趣之处在于,输出行(显然)在 stderr 上,这是我没有预料到的。通信文档(docs.python.org/2.6/library/…)表明元组中的第一项应该是标准输出。被捕获的输出行看起来不像是错误,所以我不确定为什么会在那里报告(我假设 git 正在将它打印到 stderr)
标签: python git popen communicate