我需要读取git clone进程的状态(接收对象XXX%),但无法弄清楚如何。
我正在使用subprocess.Popen,但我无法弄清楚如何获取我需要的行:
proc = subprocess.Popen([GIT, "-C",IDIR+"/"+REPO,"clone",URL],shell=False,bufsize=0,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
这是典型的输出:
Cloning into 'xxx'...
remote: Reusing existing pack: 5250, done.
remote: Counting objects: 1652, done.
remote: Compressing objects: 100% (1428/1428), done.
remote: Total 6902 (delta 389), reused 0 (delta 0)
Receiving objects: XXX% (6902/6902), 27.66 MiB | 1.51 MiB/s, done.
Resolving deltas: 100% (2010/2010), done.
Checking connectivity... done.
Checking out files: 100% (3266/3266), done.
我已经在这个帖子和建议的副本中尝试了所有的建议,但似乎都没有。
这个建议导致“克隆到'测试'......完成”但没有其他输出:
popen = subprocess.Popen(["git", "clone", "https://github.com/xxx/test.git"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT,shell=False )
for line in popen.stdout:
print "out newline:"
print line
print "done"
这是不包含任何统计数据的输出:
out newline:
Cloning into 'test'...
done
答案 0 :(得分:3)
[根据评论编辑]
使用git clone
标志调用--progress
会重定向输出。
这适合我。
import subprocess
popen = subprocess.Popen(["git", "clone", "--progress", "git@bitbucket.org:xxx/yyy.git"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in popen.stdout:
print line,
print "done"
提供输出
$ python test.py
Cloning into 'yyy'...
remote: Counting objects: 1076, done.
remote: Compressing objects: 100% (761/761), done.
remote: Total 1076 (delta 488), reused 576 (delta 227)
Receiving objects: 100% (1076/1076), 6.24 MiB | 260.00 KiB/s, done.
Resolving deltas: 100% (488/488), done.
Checking connectivity... done.
done
[编辑]
就像Cristian Ciupitu所指出的那样,iter()
for line in popen.stdout:
只是{{1}}也是如此(或者不依赖于版本)。
答案 1 :(得分:0)
我假设您希望实时通信在流程仍在运行时显示某种进度。
问题是正常的stdout流是缓冲的。你需要的是无缓冲的流。您可以使用os模块获取它,例如:
fd = proc.stdout.fileno()
while proc.returncode is None:
l = os.read(fd, 1000) # Read a bit of data
print l
答案 2 :(得分:0)
我认为subprocess.communicate()
应该可以解决问题。
我通常这样做:
process=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutput,stderror=process.communicate()
for line in stdoutput:
if line.startswith('Receiving objects'):
print line
答案 3 :(得分:0)
首先,我建议将stdout和stderr组合在一起,即将{strong> Popen 与stderr=subprocess.STDOUT
一起调用。
其次,您需要使用--progress
执行 git ,因为git-clone man page说:
- 进度
Progress status is reported on the standard error stream by default when it is attached to a terminal, unless -q is specified. This flag forces progress status even if the standard error stream is not directed to a terminal.
并且您的git未附加到终端。
所以代码应如下所示:
popen = subprocess.Popen(["git", "clone", "--progress", url],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in popen.stdout:
print "out newline:"
print line
print "done"
我建议您阅读"Getting realtime output using subprocess"问题的答案,以改善您的计划。
答案 4 :(得分:0)
在描述了stderr
和--progress
的其他响应上加上标记,下面是一个完整的最小工作示例,它将实时打印git clone命令:
import os
import re
import subprocess
def test():
url = 'http://github.com/octocat/Hello-World/'
output = subprocess.Popen(['git', 'clone', '--progress', url], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
fd = output.stderr.fileno()
while True:
lines = os.read(fd,1000).decode('utf-8')
lines = re.split('\n|\r', lines)
for l in lines:
if l != '':
print(l)
if len(lines) == 1:
break
print('Press enter to continue.')