Paramiko:使用' select'进行长shell脚本输出的异步读取

时间:2014-07-10 09:23:31

标签: python python-2.7 ssh paramiko

我从here获得了以下代码,几乎没有修改:

#!/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%。这意味着此选择函数不会等到一个或多个文件描述符为某种I / O做好准备。据我所知,这是繁忙的循环问题,其中'while ... loop'将连续迭代,甚至没有呈现用于读取的数据。我怎么能让它异步读取远程输出?

1 个答案:

答案 0 :(得分:2)

您的问题是您在选择时将超时设置为0秒,因此它根本不会阻止。默认是在必要时阻止,因此要么从select取出超时参数,要么将其更改为更大的值:

r, w, x = select.select([channel], [], [])

r, w, x = select.select([channel], [], [], 10.0)

您可以在CPU中看到差异,也可以在while true之后添加一个简单的打印语句。在0.0秒的超时语句中,您将看到它连续命中。在更大的超时情况下,您会看到它只打一次(并且cpu低得多)。