我有一个可以执行的程序
./install.sh
Run Code Online (Sandbox Code Playgroud)
这安装了一堆东西,并在屏幕上发生了很多活动..
现在,我正试图通过它来执行它
p = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
Run Code Online (Sandbox Code Playgroud)
希望屏幕上发生的所有活动都在out(或err)中捕获.但是,内容在进程运行时直接打印到终端,而不是捕获到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
Run Code Online (Sandbox Code Playgroud)
......相比之下,对于不起作用的案例的证明:
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,内容直接写入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
Run Code Online (Sandbox Code Playgroud)