当前位置 : 主页 > 编程语言 > python >

Python中paramiko模块的基础操作与排错问题

来源:互联网 收集:自由互联 发布时间:2023-01-30
目录 关于 应用 安装 示例 1.秘钥登陆 2.单个命令执行 3.执行多个命令 4.SFTPClient下载文件 5.上传文件 6.ssh工具封装 补充 学习参考 关于 python的ssh库操作需要引入一个远程控制的模块par
目录
  • 关于
  • 应用
  • 安装
  • 示例
    • 1.秘钥登陆
    • 2.单个命令执行
    • 3.执行多个命令
    • 4.SFTPClient下载文件
    • 5.上传文件
    • 6.ssh工具封装
  • 补充
    • 学习参考

      关于

      python的ssh库操作需要引入一个远程控制的模块——paramiko,可用于对远程服务器进行命令或文件操作。

      应用

      登陆服务器,问题排查。可用于编写脚本,在服务器上做一些繁琐的重复操作。

      安装

      打开cmd,输入命令python -m pip install paramiko

      示例

      1.秘钥登陆

      配置免密登录,linux上信任了windows的公钥,然后脚本在windows上跑,使用windows的私钥就可以直接不要密码登录linux

      注意:提供秘钥的paramiko.RSAKey.from_private_key_file('文件'),这里面的"文件"是你本机上的秘钥,不是指你被控机上的公钥哦!

      import paramiko
      
      key = paramiko.RSAKey.from_private_key_file("C:\\Users\\liyansheng\\.ssh\\id_rsa")
      ssh = paramiko.SSHClient()
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      print("connecting")
      ssh.connect(hostname="192.168.220.128", username="root", pkey=key)
      print("connected")
      commands = "uname -a"
      stdin, stdout, stderr = ssh.exec_command(commands)
      stdin.close()
      res, err = stdout.read(), stderr.read()
      result = res if res else err
      print(result)
      ssh.close()
      
      if __name__ == '__main__':
          print()
      

      2.单个命令执行

      创建一个.py文件,引入 paramiko模块
      import paramiko
      1. 建立SSHClient对象
      ssh = paramiko.SSHClient()
      1. 设置可信任,将主机加到host_allow列表
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      1. 创建连接
      ssh.connect("150.158.16.123", 22, "wuyanping", "2022")
      1. 创建命令,发送并获取响应结果
       stdin, stdout, stderr = ssh.exec_command("ls /home")
          print(stdout.read().decode("utf-8"))
      1. 关闭连接
      ssh.close()

      3.执行多个命令

      # 执行多条命令,注意传入的参数有个list
      def execMultiCmd(host, user, psw, cmds: list, port=22) -> (str, str):
          with paramiko.SSHClient() as ssh_client:
              ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
              ssh_client.connect(hostname=host, port=port, username=user, password=psw)
              cmd = ";".join(cmds)
              _, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True)
              result = stdout.read().decode('utf-8')
              err = stderr.read().decode('utf-8')
          return result, err
      
      
      if __name__ == '__main__':
          cmdList = ["cd /home", "ls"]
          print(execMultiCmd("192.168.220.128", "root", "root", cmdList))
      

      4.SFTPClient下载文件

      方法封装:

      def down_file(host, user, psw, local_file, remote_file, port=22):
          with paramiko.Transport((host, port)) as transport:
              # 连接服务
              transport.connect(username=user, password=psw)
              # 获取SFTP示例
              sftp = paramiko.SFTPClient.from_transport(transport)
              # 下载
              sftp.get(remote_file, local_file)
              transport.close()
      

      问题:(错误)

      if __name__ == '__main__':
          down_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download", "/home/test.txt")
      
      Traceback (most recent call last):
        File "D:\MyCode2\py-1\ssh\download.py", line 17, in <module>
          down_file("192.168.220.128", "root", "root", "D:\\ssh_download", "/home/test.txt")
        File "D:\MyCode2\py-1\ssh\download.py", line 11, in down_file
          sftp.get(remote_file, local_file)
        File "D:\MyCode2\py-1\venv\lib\site-packages\paramiko\sftp_client.py", line 810, in get
          with open(localpath, "wb") as fl:
      PermissionError: [Errno 13] Permission denied: 'D:\\ssh_download'
      

      正确使用

      要指定下载的文件名,不能只是一个目录

      if __name__ == '__main__':
          down_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download\\test.txt", "/home/test.txt")
      

      5.上传文件

      def upload_file(host, user, psw, local_file, remote_file, port=22):
          with paramiko.Transport((host, port)) as transport:
              # 连接服务
              transport.connect(username=user, password=psw)
              # 获取SFTP示例
              sftp = paramiko.SFTPClient.from_transport(transport)
              sftp.put(local_file, remote_file)
              transport.close()
      

      测试同下载,特别要注意路径问题。如

      if __name__ == '__main__':
          upload_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download\\test123.txt", "/home/test/test123.txt")
      

      6.ssh工具封装

      import os
      
      import paramiko
      
      
      class SSHTool():
          def __init__(self, ip, port, user, psw):
              """
              初始化
              :param ip:
              :param port:
              :param user:
              :param psw:
              """
              self.ip = ip
              self.port = port
              self.user = user
              self.psw = psw
      
          def connect_ssh(self):
              """
              创建连接
              :return:
              """
              try:
                  self.ssh = paramiko.SSHClient()
                  self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                  self.ssh.connect(
                      hostname=self.ip,
                      port=self.port,
                      username=self.user,
                      password=self.psw
                  )
              except Exception as e:
                  print(e)
              return self.ssh
      
          def close_ssh(self):
              """
              关闭连接
              :return:
              """
              try:
                  self.ssh.close()
              except Exception as e:
                  print(e)
      
          def exec_shell(self, shell):
              ssh = self.connect_ssh()
              try:
                  stdin, stdout, stderr = ssh.exec_command(shell)
                  return stdin, stdout, stderr
              except Exception as e:
                  print(e)
      
          def sftp_put_file(self, file, local_dir, remote_dir):
              try:
                  t = paramiko.Transport((self.ip, self.port))
                  t.connect(username=self.user, password=self.psw)
                  sftp = paramiko.SFTPClient.from_transport(t)
                  sftp.put(os.path.join(local_dir, file), remote_dir)
                  t.close()
              except Exception:
                  print("connect error!")
      
          def sftp_get_file(self, file, local_dir, remote_dir):
              try:
                  t = paramiko.Transport((self.ip, self.port))
                  t.connect(username=self.user, password=self.psw)
                  sftp = paramiko.SFTPClient.from_transport(t)
                  sftp.get(remote_dir, os.path.join(local_dir, file))
                  t.close()
              except Exception:
                  print("connect error!")
      
      

      补充

      获取当前文件路径:os.getcwd()

      import os
      
      if __name__ == '__main__':
          print(os.getcwd())  # D:\MyCode2\py-1\ssh
      

      python函数返回多个参数

      def get_strs() -> (str, str):
          return "hello", "word"
      if __name__ == '__main__':
          # 返回值为元祖的形式
          print(get_strs())  # ('hello', 'word')
          # 获取元祖的个数
          print(len(get_strs()))  # 2
          # 通过下标获取元祖的某一个值
          print(get_strs().__getitem__(1))  # word
          # 通过元祖的某个元素定位对应的下标
          print(get_strs().index("hello"))  # 0
      

      with … as …使用

      为了更好地避免此类问题,不同的编程语言都引入了不同的机制。在 Python 中,对应的解决方式是使用 with as 语句操作上下文管理器(context manager),它能够帮助我们自动分配并且释放资源。简单的理解,同时包含 enter() 和 exit() 方法的对象就是上下文管理器。

      格式:

      with 表达式 [as target]:
          代码块
      

      学习参考

      • Python]远程SSH库Paramiko简介_alwaysrun的博客-CSDN博客_python ssh库
      • Python with as用法详解 (biancheng.net)
      • Python中的with-as用法 - 简书 (jianshu.com)

      到此这篇关于Python学习之paramiko模块的基础操作与排错的文章就介绍到这了,更多相关Python paramiko模块内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

      上一篇:Python实现K-近邻算法的示例代码
      下一篇:没有了
      网友评论