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

时间:2015-01-13 23:45:12

标签: python

我有一个可以作为

执行的程序
./install.sh

这会安装很多东西,并且在屏幕上发生了很多活动..

现在,我正试图通过

执行它
p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

希望在out(或err)中捕获屏幕上发生的所有活动。但是,在流程运行时,内容会直接打印到终端,而不会被捕获到outerr,这些流程在运行后都是空的。

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

1 个答案:

答案 0 :(得分:6)

一般而言,您正在做的事情已足以将所有输出传递给您的变量。

一个例外是,如果您正在运行的程序使用/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

...相反,为了演示的情况:

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

在这种情况下,内容直接写入TTY,而不是stdout或stderr。如果不使用提供虚假TTY的程序(例如scriptexpect),则无法捕获此内容。所以,要使用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