【发布时间】:2014-09-23 03:47:03
【问题描述】:
我有一个用 python 编写的程序,并在其中使用了 git 命令。
出于某种原因,我不想使用 git-python 或其他代替子进程。
但我目前无法获得git clone 输出。
我尝试了一些代码 sn-p。有些适用于ping 8.8.8.8 等命令,但不适用于git clone。
例如
使用线程
def log_worker(stdout):
while True:
last = non_block_read(stdout).strip()
if last != "":
print(last)
def non_block_read(output):
fd = output.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
try:
return output.read()
except:
return ''
def test():
mysql_process = subprocess.Popen(
"ping google.com",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
thread = Thread(target=log_worker, args=[mysql_process.stdout])
thread.daemon = True
thread.start()
mysql_process.wait()
thread.join(timeout=1)
test()
或
newlines = ['\n', '\r\n', '\r']
def unbuffered(proc, stream='stdout'):
stream = getattr(proc, stream)
with contextlib.closing(stream):
while True:
print('tt')
out = []
last = stream.read(1)
# Don't loop forever
if last == '' and proc.poll() is not None:
break
print('last', last)
while last not in newlines:
print("loop")
# Don't loop forever
if last == '' and proc.poll() is not None:
break
out.append(last)
last = stream.read(1)
out = ''.join(out)
yield out
def example():
cmd = ['ls', '-l', '/']
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
# Make all end-of-lines '\n'
universal_newlines=True,
shell = True
)
for line in unbuffered(proc):
print('new line')
print line
example()
也是最常见的一种
for line in iter(proc.stdout.readline, ''):
sys.stdout.write('{:.2f} {}\n'.format(
time.time() - start,
line.rstrip()
))
sys.stdout.flush()
它们都适用于ping google.com,但不适用于git clone。
有没有办法解决这个问题?
提前致谢!
更新1:
面对现实,我只想获得git clone 的完成百分比。不需要日志或任何日志文件。
【问题讨论】:
-
你为什么使用
shell=True(尤其是你使用的是参数列表而不是shell命令行)? -
subprocess.check_output 会不会容易很多?
-
另外,最后一个版本“最常见”是什么意思?您什么时候需要日志样式的时间戳但又不想使用
logging模块?
标签: python git subprocess