Paramiko:使用'select'异步读取长Shell脚本输出
我有一段代码,来自这里,我稍微修改了一下:
#!/usr/bin/env python
import paramiko
import select
server = "192.168.100.100"
port = 22
name = "root"
password = "pass"
def main():
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
client.connect(server, port, name, password)
channel = client.get_transport().open_session()
channel.exec_command("/tmp/test.sh")
while True:
if channel.exit_status_ready():
break
r, w, x = select.select([channel], [], [], 0.0)
if len(r) > 0:
print channel.recv(1024)
if __name__ == "__main__":
main()
其中,test.sh的内容如下:
#!/usr/bin/env bash
while true
do
echo "Message"
sleep 1
done
执行这个Python脚本后,CPU的使用率飙升到100%。这意味着这个选择函数并没有等到一个或多个文件描述符准备好进行输入输出操作。根据我的理解,这就是所谓的“忙循环”问题,也就是‘while ... loop’会不断循环,即使没有数据可以读取。请问我该如何实现异步读取远程输出呢?
1 个回答
3
你的问题是你在使用 select
时把超时时间设置成了0秒,这样就不会阻塞了。默认情况下,它会一直等待,直到有数据可用。所以你可以把 select
的超时参数去掉,或者把它改成一个更大的值:
r, w, x = select.select([channel], [], [])
或者
r, w, x = select.select([channel], [], [], 10.0)
你可以通过观察CPU的使用情况,以及在你的 while true
循环后加一个简单的打印语句,来看到这两者的区别。在0.0秒的超时设置下,你会看到它一直在运行。而在更大的超时设置下,你会看到它只运行了一次(而且CPU的使用率也会低很多)。