Capturing *all* terminal output of a program called from Python

前端 未结 1 977
长情又很酷
长情又很酷 2020-12-22 10:19

I have a program which can be execute as

./install.sh

This install bunch of stuff and has quite a lot of activity happening on screen..

相关标签:
1条回答
  • 2020-12-22 11:04

    In general, what you're doing is already sufficient to channel all output to your variables.

    One exception to that is if the program you're running is using /dev/tty to connect directly to its controlling terminal, and emitting output through that terminal rather than through stdout (FD 1) and stderr (FD 2). This is commonly done for security-sensitive IO such as password prompts, but rarely seen otherwise.


    As a demonstration that this works, you can copy-and-paste the following into a Python shell exactly as given:

    import subprocess
    executable = ['/bin/sh', '-c', 'echo stdout; echo stderr >&2']
    p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
    print "---"
    print "output: ", out
    print "stderr: ", err
    

    ...by contrast, for a demonstration of the case that doesn't work:

    import subprocess
    executable = ['/bin/sh', '-c', 'echo uncapturable >/dev/tty']
    p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
    print "---"
    print "output: ", out
    

    In this case, content is written to the TTY directly, not to stdout or stderr. This content cannot be captured without using a program (such as script or expect) that provides a fake TTY. So, to use script:

    import subprocess
    executable = ['script', '-q', '/dev/null',
                  '/bin/sh', '-c', 'echo uncapturable >/dev/tty']
    p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
    print "---"
    print "output: ", out
    
    0 讨论(0)
提交回复
热议问题