使paramiko库执行命令时,在给定的时间强制退出
原因:
使用paramiko库ssh连接到远端云主机上时,非常偶现卡死现象,连接无法退出(可以是执行命令时云主机重启等造成)。需要给定一段时间,不管命令执行是否卡住,都退出连接,显示命令执行超时错误。
实现方式:
线程+事件,在线程中执行ssh命令,给事件配置超时时间。
代码示例:
1 from threading import Thread, Event
2 import paramiko
1 class SshClient(object): 2 3 def __init__(self, ip, port, username, password): 4 self.ip = ip 5 self.host = host 6 self.username = username 7 self.password = password 8 9 def exec_command(cmd, timeout): 10 log.info(u"在ip:%s上执行命令%s" % (self.ip, cmd)) 11 sc = paramiko.SSHClient() 12 sc.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 13 14 # 用来接收stdout stderror status信息 15 res = [None, None, None] 16 17 def get_return(start_event, res_list): 18 _, cmd_stdout, cmd_stderr = sc.exec_command(command=cmd, timeout=timeout) 19 channel = cmd_stdout.channel 20 cmd_status = channel.recv_exit_status() 21 res_list[0] = cmd_stdout 22 res_list[1] = cmd_stderr 23 res_list[2] = cmd_status 24 start_event.set() # 表示线程已经执行完毕 25 26 try: 27 sc.connect(hostname=self.ip, port=self.port, username=self.username, password=self.password, timeout=30) # 这里的timeout是连接使用的,与我们要的不同 28 start_evt = Event() 29 t = Thread(target=get_return, args=(start_evt, res)) 30 t.start() 31 start_evt.wait(timeout=timeout) 32 # 执行到这里说明线程已经退出 33 if None in res: 34 raise Exception(u"命令超时退出") 35 stdout, stderr, status = res 36 if status != 0: 37 raise Exception(u"命令执行返回非0!返回值为%s,错误信息为%s" % (status, stdout.read() + stderr.read())) 38 return stdout.read() + stderr.read() 39 finally: 40 sc.close() 41 }