使paramiko库执行命令时在给定的时间强制退出功能的实现


Posted in Python onMarch 03, 2021

使用paramiko库ssh连接到远端云主机上时,非常偶现卡死现象,连接无法退出(可以是执行命令时云主机重启等造成)。需要给定一段时间,不管命令执行是否卡住,都退出连接,显示命令执行超时错误。

实现方式:

线程+事件,在线程中执行ssh命令,给事件配置超时时间。

代码示例:

1 from threading import Thread, Event

2 import paramiko

class SshClient(object):

  def __init__(self, ip, port, username, password):
    self.ip = ip
    self.host = host
    self.username = username
    self.password = password

  def exec_command(cmd, timeout):
    log.info(u"在ip:%s上执行命令%s" % (self.ip, cmd))
    sc = paramiko.SSHClient()
    sc.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    # 用来接收stdout stderror status信息
    res = [None, None, None]

    def get_return(start_event, res_list):
      _, cmd_stdout, cmd_stderr = sc.exec_command(command=cmd, timeout=timeout)
      channel = cmd_stdout.channel
      cmd_status = channel.recv_exit_status()
      res_list[0] = cmd_stdout
      res_list[1] = cmd_stderr
      res_list[2] = cmd_status
      start_event.set()  # 表示线程已经执行完毕

    try:
      sc.connect(hostname=self.ip, port=self.port, username=self.username, password=self.password, timeout=30)  # 这里的timeout是连接使用的,与我们要的不同
      start_evt = Event()
      t = Thread(target=get_return, args=(start_evt, res))
      t.start()
      start_evt.wait(timeout=timeout)
      # 执行到这里说明线程已经退出
      if None in res:
        raise Exception(u"命令超时退出")
      stdout, stderr, status = res
      if status != 0:
        raise Exception(u"命令执行返回非0!返回值为%s,错误信息为%s" % (status, stdout.read() + stderr.read()))
      return stdout.read() + stderr.read()
    finally:
      sc.close()
}

知识点补充:

python paramiko的使用介绍

一: 使用paramiko

#设置ssh连接的远程主机地址和端口
t=paramiko.Transport((ip,port))
#设置登录名和密码
t.connect(username=username,password=password)
#连接成功后打开一个channel
chan=t.open_session()
#设置会话超时时间
chan.settimeout(session_timeout)
#打开远程的terminal
chan.get_pty()
#激活terminal
chan.invoke_shell()

然后就可以通过chan.send('command')和chan.recv(recv_buffer)来远程执行命令以及本地获取反馈。

 二: paramiko的两个模块介绍

paramiko有两个模块SSHClient()和SFTPClient()

SSHClient()的使用代码:

import paramiko

ssh = paramiko.SSHClient() # 创建SSH对象
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.2.103', port=22, username='root', password='123456')

stdin, stdout, stderr = ssh.exec_command('ls') # 执行命令
result = stdout.read() # 获取命令结果
print (str(result,encoding='utf-8'))
ssh.close() # 关闭连接

SSHClient()里有个transport变量,是用于获取连接,我们也可单独的获取到transport变量,然后执行连接操作

import paramiko

transport = paramiko.Transport(('192.168.2.103', 22))
transport.connect(username='root', password='123456')

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
print (str(stdout.read(),encoding='utf-8'))

transport.close()

用transport实现上传下载以及命令的执行:

#coding:utf-8
import paramiko
import uuid

class SSHConnection(object):

def __init__(self, host='192.168.2.103', port=22, username='root',pwd='123456'):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None

def connect(self):
transport = paramiko.Transport((self.host,self.port))
transport.connect(username=self.username,password=self.pwd)
self.__transport = transport

def close(self):
self.__transport.close()

def upload(self,local_path,target_path):
# 连接,上传
# file_name = self.create_file()
sftp = paramiko.SFTPClient.from_transport(self.__transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(local_path, target_path)

def download(self,remote_path,local_path):
sftp = paramiko.SFTPClient.from_transport(self.__transport)
sftp.get(remote_path,local_path)

def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 获取命令结果
result = stdout.read()
print (str(result,encoding='utf-8'))
return result

ssh = SSHConnection()
ssh.connect()
ssh.cmd("ls")
ssh.upload('s1.py','/tmp/ks77.py')
ssh.download('/tmp/test.py','kkkk',)
ssh.cmd("df")
ssh.close()

到此这篇关于使paramiko库执行命令时,在给定的时间强制退出的文章就介绍到这了,更多相关paramiko库执行命令内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中使用装饰器和元编程实现结构体类实例
Jan 28 Python
Python 基于Twisted框架的文件夹网络传输源码
Aug 28 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
Feb 16 Python
Python Flask基础教程示例代码
Feb 07 Python
python批量下载网站马拉松照片的完整步骤
Dec 05 Python
Pandas之Fillna填充缺失数据的方法
Jun 25 Python
pycharm中显示CSS提示的知识点总结
Jul 29 Python
对Python获取屏幕截图的4种方法详解
Aug 27 Python
python多线程实现TCP服务端
Sep 03 Python
django在开发中取消外键约束的实现
May 20 Python
python对 MySQL 数据库进行增删改查的脚本
Oct 22 Python
Python基础之tkinter图形化界面学习
Apr 29 Python
python上下文管理的使用场景实例讲解
Mar 03 #Python
pip install命令安装扩展库整理
Mar 02 #Python
python实现杨辉三角的几种方法代码实例
Mar 02 #Python
python爬虫破解字体加密案例详解
Mar 02 #Python
python包的导入方式总结
Mar 02 #Python
numpy实现RNN原理实现
Mar 02 #Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
Mar 02 #Python
You might like
谈谈PHP语法(2)
2006/10/09 PHP
PHP date函数参数详解
2006/11/27 PHP
Apache2中实现多网站域名绑定的实现方法
2011/06/01 PHP
php文档更新介绍
2011/07/22 PHP
PHP在获取指定目录下的目录,在获取的目录下面再创建文件,多平台
2011/08/03 PHP
php校验表单检测字段是否为空的方法
2015/03/20 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
jQuery1.5.1 animate方法源码阅读
2011/04/05 Javascript
密码强度检测效果实现原理与代码
2013/01/04 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
JavaScript 上万关键字瞬间匹配实现代码
2013/07/07 Javascript
$("").click与onclick的区别示例介绍
2014/09/25 Javascript
jQuery实现数字加减效果汇总
2014/12/16 Javascript
$.extend 的一个小问题
2015/06/18 Javascript
JavaScript获取css行间样式,内连样式和外链样式的简单方法
2016/07/18 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
2016/12/20 Javascript
jQuery EasyUI window窗口使用实例代码
2017/12/25 jQuery
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
详解JavaScript 中 if / if...else...替换方式
2018/07/15 Javascript
解决layui checkbox 提交多个值的问题
2019/09/02 Javascript
layui点击左侧导航栏,实现不刷新整个页面,只刷新局部的方法
2019/09/25 Javascript
jquery实现掷骰子小游戏
2019/10/24 jQuery
关于vue的列表图片选中打钩操作
2020/09/09 Javascript
Openlayers绘制地图标注
2020/09/28 Javascript
[02:33]DOTA2亚洲邀请赛趣味视频之吐真话筒
2018/03/31 DOTA
[53:15]Newbee vs Pain 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python 中random模块的常用方法总结
2017/07/08 Python
Python中socket网络通信是干嘛的
2020/05/27 Python
Python函数调用追踪实现代码
2020/11/27 Python
教师实习自我鉴定
2013/12/14 职场文书
群众路线教育实践活动个人对照检查材料思想汇报(社区班子)
2014/10/06 职场文书
yolov5返回坐标的方法实例
2022/03/17 Python
oracle delete误删除表数据后如何恢复
2022/06/28 Oracle
JS class语法糖的深入剖析
2022/07/07 Javascript
使用python生成大量数据写入es数据库并查询操作(2)
2022/09/23 Python