Python capture popen stdout and display on console?

I want to write stdout from a long-ish running process launched through subprocess.Popen(...), so I use stdout=PIPEas arg.

However, since this is a lengthy process, I also want to send the output to the console (as if I hadn't missed it) to give the script user the idea that it is still working.

Is it possible?

Greetings.

+5
source share
5 answers

Can you just printread it by reading it from the channel?

+1
source

, , , UX. pexpect (, Windows, wexpect), ​​ , . ( unix-y, pexpect):

>>> import pexpect
>>> child = pexpect.spawn('/bin/bash -c "echo ba; sleep 1; echo bu"', logfile=sys.stdout); x=child.expect(pexpect.EOF); child.close()
ba
bu
>>> child.before
'ba\r\nbu\r\n'

ba bu ( ). , , - ( .replace!)), \n ( , stdout - , !).

+5

S. Lott stdout Python

, 1085071. ...

, , , , .

, - , pexpect/wexpect ?

+2

Alternatively, you can connect your process to a tee and capture only one of the threads. Something along the lines sh -c 'process interesting stuff' | tee /dev/stderr.

Of course, this only works on Unix-like systems.

+1
source

Inspired by the pty.openpty () clause somewhere above, tested on python2.6, linux. Publishing, as it took some time to get it right, without buffering ...

def call_and_peek_output(cmd, shell=False):
    import pty, subprocess
    master, slave = pty.openpty()
    p = subprocess.Popen(cmd, shell=shell, stdin=None, stdout=slave, close_fds=True)
    os.close(slave)
    line = ""
    while True:
        try:
            ch = os.read(master, 1)
        except OSError:
            # We get this exception when the spawn process closes all references to the
            # pty descriptor which we passed him to use for stdout
            # (typically when it and its childs exit)
            break
        line += ch
        sys.stdout.write(ch)
        if ch == '\n':
            yield line
            line = ""
    if line:
        yield line

    ret = p.wait()
    if ret:
        raise subprocess.CalledProcessError(ret, cmd)

for l in call_and_peek_output("ls /", shell=True):
    pass
+1
source

All Articles