【Python】Paramiko模块_连接SFTP上传下载执行命令

Paramiko模块

是基于Python实现的SSH远程安全连接,用于SSH远程执行命令、文件传输等功能。

paramiko 2.4.2 依赖 cryptography,是使用SSHv2协议(底层使用的是cryptography)的一个第三方的库

pip install paramiko==2.4.2
pip install cryptography==2.4.2  # 2.5取消了部分功能

 

 

实现sftp上传下载及执行命令功能

import paramiko
from logger import *  # 实现logs打印及config配置文件获取

class SFTP_tools():
    """连接SFTP操作工具,上传下载执行命令"""

    def __init__(self, type):
        """
        构造函数
        :param type: 根据type获取本地及服务器端路径,暂且支持a,b 
        """
        self.host = config.get("sftp_msg", "sftpHost")
        self.port = config.get("sftp_msg", "sftpPort")
        self.user = config.get("sftp_msg", "sftpUserName")
        self.password = config.get("sftp_msg", "sftpPassword")
        self.type = type
        # 根据功能判断服务器及本地文件路径
        if self.type == "a":
            self.server_path = config.get("sftp_msg", "sftpPath.serverpath.a")
            self.local_path = config.get("sftp_msg", "sftpPath.localpath.a")
        elif self.type == "b":
            self.server_path = config.get("sftp_msg", "sftpPath.serverpath.b")
            self.local_path = config.get("sftp_msg", "sftpPath.localpath.b")
        else:
            logs.error("type传值错误,暂且仅支持a、b文件的上传下载")
            sys.exit()
        logs.info("======== SFTP连接信息 ========")
        logs.info("sftp连接服务器地址 - {}:{}".format(self.host, self.port))
        logs.info("sftp连接服务器用户 - {}/{}".format(self.user, self.password))

    def sftp_upload_file(self, file, timeout=10):
        """
        SFTP上传文件,注意:不支持文件夹
        :param file:需要上传的文件名,如:test.txt
        :param timeout: 超时时间(默认),必须是int类型
        :return: bool
        """

        logs.info("sftp服务器路径:{}".format(self.server_path+file))
        logs.info("sftp本地路径:{}".format(self.local_path+file))

        try:
            # 设置SSH连接的远程主机地址和端口
            t = paramiko.Transport((self.host, int(self.port)))
            # 设置连接超时时间
            t.banner_timeout = timeout
            # 设置登陆用户名和密码等参数
            t.connect(username=self.user, password=self.password)
            # SFTPClient作为一个SFTP客户端对象,根据SSH传输协议的sftp会话,实现远程文件操作,比如文件上传、下载、权限、状态等操作。
            # from_transport创建一个已连通的SFTP客户端通道
            sftp = paramiko.SFTPClient.from_transport(t)
            # 将本地文件上传到远程SFTP服务端
            sftp.put(self.local_path+file, self.server_path+file)
            logs.info(">>> sftp 上传文件:{}".format(file))
            # t.close()
            return True
        except Exception as e:
            logs.error("sftp上传操作异常,异常原因:{}".format(e))
            # t.close()
            return False
        finally:
            # 关闭连接
            t.close()
            logs.info("======= sftp 连接关闭 =======")

    def sftp_download_file(self, file, timeout=10):
        """
        下载文件,注意:不支持文件夹
        :param timeout: 超时时间(默认),必须是int类型
        :param file:需要下载的文件名,如:test.txt
        :return: bool
        """

        logs.info("sftp服务器路径:{}".format(self.server_path+file))
        logs.info("sftp本地路径:{}".format(self.local_path+"/download/"+file))

        try:
            # 设置SSH连接的远程主机地址和端口
            t = paramiko.Transport((self.host, int(self.port)))
            # 设置连接超时时间
            t.banner_timeout = timeout
            # 设置登陆用户名和密码等参数
            t.connect(username=self.user, password=self.password)
            # SFTPClient作为一个SFTP客户端对象,根据SSH传输协议的sftp会话,实现远程文件操作,比如文件上传、下载、权限、状态等操作。
            # from_transport创建一个已连通的SFTP客户端通道
            sftp = paramiko.SFTPClient.from_transport(t)
            # 从远程SFTP服务端下载文件到本地
            sftp.get(self.server_path+file, self.local_path+"/download/"+file)
            logs.info(">>> sftp 下载文件:{}".format(self.local_path+"/download/"+file))
            return True
        except Exception as e:
            logs.error("sftp下载操作异常,异常原因:{}".format(e))
            return False
        finally:
            # 关闭连接
            t.close()
            logs.info("======= sftp 连接关闭 =======")

    def ssh_exec_command(self, cmd, timeout=10):
        """
        使用ssh连接远程服务器执行命令
        :param cmd: 执行的命令
        :param seconds: 超时时间(默认),必须是int类型
        :return: dict
        """
        result = {'status': 1, 'data': None}  # 返回结果
        try:
            # 创建一个新的SSHClient实例
            ssh = paramiko.SSHClient() 
            # 设置SSHClient超时时间
            ssh.banner_timeout = timeout
            # 设置host key,如果在"known_hosts"中没有保存相关的信息, SSHClient 默认行为是拒绝连接, 会提示yes/no
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # 连接远程服务器,超时时间1秒
            ssh.connect(self.host, self.port, self.user, self.password, timeout=timeout)
            # 执行命令
            stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True, timeout=timeout)
            # 执行结果,readlines会返回列表
            out = stdout.readlines()
            # 执行状态,0表示成功,1表示失败
            channel = stdout.channel
            status = channel.recv_exit_status()
            # 关闭ssh连接
            ssh.close()
            # 修改返回结果
            result['status'] = status
            result['data'] = out
            return result
        except Exception as e:
            print(e)
            print("错误, 登录服务器或者执行命令超时!!! ip: {} 命令: {}".format(self.host, cmd))
            return False

if __name__ == '__main__':
    type = "a"
    file = "test.txt"
    
    # 调用
    sftp = SFTP_tools(type)
    # sftp.sftp_download_file(file)        # 下载
    sftp.sftp_upload_file(file)        # 上传

 

 

 

拓展

连接远程connect 参数说明

  hostname(str类型):连接的目标主机地址;
  port(int类型):连接目标主机的端口,默认为22;
  username(str类型):校验的用户名(默认为当前的本地用户名);
  password(str类型):密码用于身份校验或解锁私钥;
  pkey(Pkey类型):私钥方式用于身份验证;
  key_filename(str or list(str)类型):一个文件名或文件名列表,用于私钥的身份验证;
  timeout(float类型):一个可选的超时时间(以秒为单位)的TCP连接;
  allow_agent(bool类型):设置为False时用于禁用连接到SSH代理;
  look_for_keys(bool类型):设置为False时用于来禁用在~/.ssh中搜索私钥文件;
  compress(bool类型):设置为True时打开压缩。

 

SFTPClient类其它常用方法说明

  mkdir:在SFTP服务端创建目录

    如:sftp.mkdir("/home/userdir",mode=0777),默认模式是0777(八进制),在某些系统上,mode被忽略。在使用它的地方,当前的umask值首先被屏蔽掉。

  remove:删除SFTP服务端指定目录

    如:sftp.remove("/home/userdir")。

  rename:重命名SFTP服务端文件或目录

    如:sftp.rename("/home/test.sh","/home/testfile.sh")

  stat:获取远程SFTP服务端指定文件信息
    如:sftp.stat("/home/testfile.sh")。

  listdir:获取远程SFTP服务端指定目录列表,以Python的列表(List)形式返回

    如:sftp.listdir("/home")。

 

posted @ 2023-01-07 17:04  Phoenixy  阅读(1530)  评论(0)    收藏  举报