有没有办法在Python中显示shell命令的输出,因为命令运行?
我有以下代码将命令发送到特定 shell(在本例中为/bin/tcsh
):
import subprocess
import select
cmd = subprocess.Popen(['/bin/tcsh'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
poll = select.poll()
poll.register(cmd.stdout.fileno(),select.POLLIN)
# The list "commands" holds a list of shell commands
for command in commands:
cmd.stdin.write(command)
# Must include this to ensure data is passed to child process
cmd.stdin.flush()
ready = poll.poll()
if ready:
result = cmd.stdout.readline()
print result
另外,我从this thread获得了上面的代码,但我不确定我是否了解轮询机制的工作原理。
ready
传递给timeout
,为什么我需要变量poll.poll()
?答案 0 :(得分:1)
是的,当命令运行时,完全可以显示shell comamand的输出。有两个要求:
1)该命令必须刷新其输出。
许多程序根据输出是连接到终端,管道还是文件来缓冲输出。如果它们连接到管道,它们可能会更频繁地将它们的输出写入更大的块。对于您执行的每个程序,请参阅其文档。例如,/bin/cat'
的某些版本具有-u
开关。
2)你必须逐个阅读它,而不是一次性阅读。
您的程序必须从输出流中一次构建一个部分。这意味着你不应该这样做,每次都读取整个流:
cmd.stdout.read()
for i in cmd.stdout:
list(cmd.stdout.readline())
但相反,你可以做其中一个:
while not_dead_yet:
line = cmd.stdout.readline()
for line in iter(cmd.stdout.readline, b''):
pass
现在,针对您的三个具体问题:
有没有办法在Python中显示shell命令的输出,因为命令运行?
是的,但前提是您运行的命令在运行时输出,并且不会将其保存到最后。
上面究竟注册了什么?
文件描述符,当读取时,使子进程的输出可用。
如果我没有向poll.poll()传递任何超时,为什么我需要变量就绪?
你没有。您也不需要poll()
。如果您的commands
列表相当大,则可能需要poll()
两者 stdin和stdout流以避免死锁。但是如果你的commands
列表相当适中(小于5K字节),那么你可以在开头编写它们。
以下是一种可能的解决方案:
#! /usr/bin/python
import subprocess
import select
# Critical: all of this must fit inside ONE pipe() buffer
commands = ['echo Start\n', 'date\n', 'sleep 10\n', 'date\n', 'exit\n']
cmd = subprocess.Popen(['/bin/tcsh'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# The list "commands" holds a list of shell commands
for command in commands:
cmd.stdin.write(command)
# Must include this to ensure data is passed to child process
cmd.stdin.flush()
for line in iter(cmd.stdout.readline, b''):
print line