我试图读取命令中的最后一行,例如' apt-get download firefox'。通常输出就像
Get:1 http://archive.ubuntu.com/ubuntu/ utopic/main firefox amd64 32.0+build1-0ubuntu2 [34.9 MB]
2% [1 firefox 646 kB/34.9 MB 2%]
最后一行不断更新(在达到100%之前不会写新行)。我的目标是现在实时阅读进展。这是我当前的示例代码:
#!/usr/bin/python3 -u
# coding=utf-8
import subprocess, sys
pipe = subprocess.Popen(['apt-get', 'download', 'firefox'], 0, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
while True:
content = pipe.stdout.read(1).decode()
if content == '':
break
sys.stdout.write(content)
sys.stdout.flush()
pipe.wait()
我已经禁用了子进程调用的输出缓冲,也禁用了Python进程的二进制输出(使用-u参数)。但我只获得了第一行而不是第二行的进展。有人知道我怎么能做到这一点吗?
答案 0 :(得分:1)
如果将apt-get
的stdout重定向到管道,例如
$ apt-get download firefox | cat
然后它不会报告进度(最后一行,例如2% [1 firefox 646 kB/34.9 MB 2%]
不在输出中)。 stdout=subprocess.PIPE
自然地创造了一条管道;因此,apt-get
不会打印您的下载进度。
如果您希望同时捕获apt-get
输出并在屏幕上实时显示最后一行(进度报告),那么您可以use pexpect
module to trick the child process into thinking that it runs in a terminal:
import sys
import pexpect # $ pip install pexpect
output, exitstatus = pexpect.runu('apt-get download firefox',
logfile=sys.stdout,
withexitstatus=1)
您只能使用stdlib pty
模块执行相同操作:
#!/usr/bin/env python3
import os
import pty
output = []
def read(fd):
data = os.read(fd, 1024)
output.append(data)
return data
status = pty.spawn(['apt-get', 'download', 'firefox'], read)
@eryksun on Python Issue tracker suggested apt-get
' --quiet
选项:
#!/usr/bin/env python3
import shlex
from io import TextIOWrapper
from subprocess import Popen, PIPE
output = []
with Popen(shlex.split("apt-get --quiet=0 download firefox"),
stdout=PIPE, bufsize=1) as p:
# recognize '\r' as newline but don't convert it to '\n'
for line in TextIOWrapper(p.stdout, newline=''):
print(line, end='', flush=True) # print to terminal
output.append(line) # save for later
print(p.returncode)