我有一个可以作为
执行的程序./install.sh
这会安装很多东西,并且在屏幕上发生了很多活动..
现在,我正试图通过
执行它p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
希望在out
(或err
)中捕获屏幕上发生的所有活动。但是,在流程运行时,内容会直接打印到终端,而不会被捕获到out
或err
,这些流程在运行后都是空的。
这里可能发生什么?如何捕获这些内容?
答案 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的程序(例如script
或expect
),则无法捕获此内容。所以,要使用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