zoukankan      html  css  js  c++  java
  • python paramiko实现ssh上传下载执行命令

    paramiko ssh上传下载执行命令

    序言

    最近项目经常需要动态在跳板机上登录服务器进行部署环境,且服务器比较多,每次完成所有服务器到环境部署执行耗费大量时间。为了解决这个问题,根据所学的执行实现了一个定时执行部署服务测试系统,其主要结构如下:
    图1
    其中图中的这几个实现如下:

    • 定时任务CI
      通过coding平台实现(https://codingcorp.coding.net/)
    • 自定义节点
      通过coding平台添加自定义节点,目前是通过linux默认的default方式显示
    • 部署命令/上传文件
      通过python的paramiko库实现

    其中coding平台已提供ci能力来显示持续部署测试,想实现该功能只需通过python来实现文件上传以及执行命令功能

    paramiko介绍

    paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。由于可通过python这种跨平台的语言运行,因此支持python平台(mac、linux、win)都能支持该功能。paramiko支持的功能很多,常用的功能如下:

    • linux命令执行
    • sftp协议执行
    • 用户名/密码、DSSKey、ECDSAKey、Ed25519Key方式登录认证

    paramiko安装简单,只需执行pip install paramiko即可

    paramiko使用

    使用paramiko发送命令的功能步骤如下:

    • 创建一个SSH对象
      self.__ssh = paramiko.SSHClient()
    • 允许连接不在know_hosts文件中的主机
      self.__ssh = paramiko.SSHClient()
    • 连接服务器
      self.__ssh.connect(hostname=self.__ip,port=self.__port,username=self.__usename,password=self.__password,timeout=timeout)
    • 发送命令
      stdin, stdout, stderr = self.__ssh.exec_command(cmd)
    • 获取接收信息
      stdout.read().decode()

    使用paramiko上传下载文件步骤如下:

    • 使用ssh链接远程主机地址
      self.__sshfile = paramiko.Transport((self.__ip,self.__port))
    • 设置登录用户名和密码
      self.__sshfile.connect(username=self.__usename, password=self.__password)
    • 创建一个SFTP客户端通道
      self.__sftp = paramiko.SFTPClient.from_transport(self.__sshfile)
    • 上传文件
      self.__sftp.put(local_path,server_path)
    • 下载文件
      self.__sftp.get(server_path,local_path)

    通过上述paramiko的使用,就能掌握该基本功能,后续我们可以通过封装的方式简化流程方便后续调用

    paramiko封装

    对于文件比较大的时候由于paramiko上传文件以及下载文件比较慢,可通过线程的方式防止阻塞,具体封装如下:

    #coding:utf-8
    import paramiko
    import time
    import threading
    
    class Ssh(object):
        __ssh = ""
        __ip = ""
        __usename =""
        __password = ""
        __port = 22
        __sshfile = ""
        __sftp = ""
        __tload = ""
        __tdown = ""
    
        def __init__(self, ip,user='root', pwd='admin', port=22,timeout=5):
            try:
                self.__ip = ip
                self.__usename = user
                self.__password = pwd
                self.__port = port
                self.__ssh = paramiko.SSHClient()
                self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                self.__ssh.connect(hostname=self.__ip,port=self.__port,username=self.__usename,password=self.__password,timeout=timeout)
    
                self.__sshfile = paramiko.Transport((self.__ip,self.__port))
                self.__sshfile.connect(username=self.__usename, password=self.__password)
                self.__sftp = paramiko.SFTPClient.from_transport(self.__sshfile)
            except Exception as  e:
                print("connect %s failed......"%self.__ip)
                self.__ssh.close()
                self.__sshfile.close()
                self.ssh_state = False
            return
    
        def sftp_upload_file(self,server_path,local_path):
            if self.ssh_state == False:
                return False
            try:
                #添加异步
                self.__tload = threading.Thread(target=self.__sftp.put,args=(local_path,server_path))
                # self.__tload.setDaemon(True)
                self.__tload.start()
            except Exception as e:
                print(e)
                return False
    
        def sftp_down_file(self,server_path,local_path):
            if self.ssh_state == False:
                return False
            try:
                #添加异步
                self.__tdown = threading.Thread(target=self.__sftp.get,args=(server_path, local_path))
                self.__tdown.start()
            except Exception as e:
                print(e)
                return False
    
        def send_command(self,cmd):
            if self.ssh_state == False:
                return False
            try:
                stdin, stdout, stderr = self.__ssh.exec_command(cmd)
                time.sleep(0.1)
            except Exception as e:
                return False
            return stdout.read().decode()
    
        def close(self):
            try:
                self.__tload.join()
                self.__tdown.join()
            except BaseException as e:
                print(e)
            self.__ssh.close()
            self.__sshfile.close()
    
    
        @property
        def ssh_state(self):
            return self.__ssh
    
        @ssh_state.setter
        def ssh_state(self,nstate):
            self.__ssh = nstate
    

    调用如下

        ssh = Ssh(ip='0.0.0.0',user='root',pwd='12345678')
        print(ssh.send_command('ls'))
        ssh.sftp_down_file("/root/xu/iptablesadd.txt","C:/iptablesadd.txt")
        ssh.sftp_upload_file("/root/xu/iptablesadd11.txt","C:/xmind3790.rar")
        ssh.close()
    
    测试
  • 相关阅读:
    表格行内编辑增删改查
    rpc远程调用开发
    gdb调试程序
    Makefile文件编写
    CentOS6.6源码编译升级GCC至4.8.2
    linux 下C语言编程库文件处理与Makefile编写
    laravel队列-让守护进程处理耗时任务
    回顾javase点滴
    服务端生成word并压缩打包下载
    pytest框架插件(用例依赖、多重校验、执行顺序、失败重跑、重复执行、标记)
  • 原文地址:https://www.cnblogs.com/package/p/15386306.html
Copyright © 2011-2022 走看看