捕获从Python调用的程序的*all*终端输出

捕获从Python调用的程序的*all*终端输出,python,Python,我有一个程序,可以执行为 ./install.sh 这是一堆东西,在屏幕上有相当多的活动发生 现在,我正试图通过 p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() 希望屏幕上发生的所有活动都能被输入输出或错误捕获。但是,在进程运行时,内容直接打印到终端,而不会捕获到out或err中,这两个文件在进程运行后都是空的 这里会发生什么

我有一个程序,可以执行为

./install.sh
这是一堆东西,在屏幕上有相当多的活动发生

现在,我正试图通过

p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
希望屏幕上发生的所有活动都能被输入输出或错误捕获。但是,在进程运行时,内容直接打印到终端,而不会捕获到out或err中,这两个文件在进程运行后都是空的


这里会发生什么?如何捕获这些内容?

一般来说,您所做的已经足以将所有输出传递到您的变量

一个例外是,如果您正在运行的程序使用/dev/tty直接连接到其控制终端,并通过该终端而不是通过stdout FD 1和stderr FD 2发出输出。这通常适用于安全敏感的IO,如密码提示,但很少有其他情况

为了证明这一点,您可以完全按照给定的方式将以下内容复制并粘贴到Python shell中:

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
…相比之下,对于不起作用的案例的演示:

在这种情况下,内容直接写入TTY,而不是stdout或stderr。如果不使用提供虚假TTY的脚本或expect等程序,则无法捕获此内容。所以,要使用脚本:


你为什么认为你错了?通过使用/dev/tty而不是stdout和stderr,程序可以绕过这种捕获,但是很少有人这样做。另一个机制是使用你所拥有的,在我看来,它应该是有效的。。。我想在不了解可执行文件以及如何运行它的情况下,很难给出任何建议……如果您认为进程直接连接到/dev/tty,可以调用os.setsid从控制终端分离。@Fraz,您是否也在检查打印错误的输出?另外,当您的程序检测到stdout未直接连接到终端时,是否确实会发出任何输出?软件检测到这种情况并表现出不同的行为并不罕见。
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
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