If stdout of apt-get
is redirected to a pipe e.g.,
$ apt-get download firefox | cat
then it doesn’t report progress (the last line e.g., 2% [1 firefox 646 kB/34.9 MB 2%]
will not be in the output). stdout=subprocess.PIPE
naturally creates a pipe; therefore apt-get
doesn’t print the download progress in your case.
If you want both to capture apt-get
output and to see it on the screen in real-time with the last line (progress report) present then you could 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)
You could do the same using only stdlib pty
module:
#!/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
‘s --quiet
option:
#!/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)