paramiko


一、远程执行命令
    • 远程执行命令,有两种方式:
      • 1、基于ssh_obj 直接连接并执行(内部也是调用transport去连接)
      • 2、基于自定义transport
    • 远程传输文件,只有一种方式
      • 1、基于自定义transport
  • 用户名密码(基于 ssh_obj )
    • import paramiko
      
      # 实例化出一个ssh对象
      ssh_obj = paramiko.SSHClient()
      ssh_obj.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # 允许添加不在konw_hosts中的主机
      
      # 用该对象去连接server并执行命令
      ssh_obj.connect(hostname='192.168.10.202', port=22, username='root', password='redhat')
      stdin, stdout, stderr = ssh_obj.exec_command('df') 
      data = stdout.read().decode()
      if not data:
          data = stderr.read().decode()  # 因为管道中内容读完就没有了,所以不能用三元运算
      print(data)
      
      # 关闭连接
      ssh_obj.close()
  • 用户名密码(自定义transport )
    • import paramiko
      
      # 重新给 transport 字段赋值
      transport = paramiko.Transport(('192.168.10.202', 22))
      transport.connect(username='root', password='redhat')
      
      # 更改该 ssh obj对象的_transport字段(创建链接并执行命令)
      ssh_obj = paramiko.SSHClient()
      ssh_obj._transport = transport
      
      stdin, stdout, stderror = ssh_obj.exec_command('df')
      data = stdout.read().decode()
      
      if not data:
          data = stderror.read().decode()
      print(data)
      
      transport.close()
  • 秘钥(基于ssh_obj):
    • import paramiko
      import os
      import sys
      
      root = os.path.dirname(os.path.abspath('__file__'))
      sys.path.append(root)
      private_key = os.path.join(root, 'id_rsa')
      
      # 创建一个ssh 对象, 并执行命令
      ssh_obj = paramiko.SSHClient()
      ssh_obj.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      
      ssh_obj.connect(hostname='192.168.10.202', port=22, username='root', key_filename=private_key)
      stdin, stdout, stderror = ssh_obj.exec_command('df')
      data = stdout.read().decode()
      ssh_obj.close()
      if not data:
          data = stderror.read().decode()
      
      print(data)
  • 秘钥(自定义transport)
    • import paramiko
      import os
      import sys
      
      root = os.path.dirname(os.path.abspath('__file__'))
      sys.path.append(root)
      sec_key = paramiko.RSAKey.from_private_key_file(os.path.join(root, 'id_rsa'))
      
      # 创建一个transport传输通道, 并指定连接参数
      transport = paramiko.Transport(('192.168.10.202', 22))
      transport.connect(username='root', pkey=sec_key)
      
      # 更改ssh 对象的使用创建的传输通道
      ssh_obj = paramiko.SSHClient()
      ssh_obj._transport = transport
      
      # 执行命令,获取结果
      stdin, stdout, stderror = ssh_obj.exec_command('ls')
      data = stdout.read().decode()
      transport.close()
      if not data:
          data = stderror.read().decode()
      
      print(data)
二、传输文件(只能通过transport来进行传输)
  • 用户名密码
    • import paramiko
      
      # 定义通道,指定连接参数
      transport = paramiko.Transport(('192.168.10.202', 22))
      transport.connect(username='root', password='redhat')
      
      # 创建链接
      sftp = paramiko.SFTPClient.from_transport(transport)
      
      # 传输文件,文件存在则覆盖,不存在则创建
      sftp.put('s1.py', '/usr/local/src/s1.py'# y一定要指定scp过去的文件名称,否则报错
      sftp.put('s1.py', '/usr/local/src/test.py') 
      transport.close()
    • import paramiko
      import os
      import sys
      
      root = os.path.dirname(os.path.abspath('__file__'))
      sys.path.append(root)
      sec_key = paramiko.RSAKey.from_private_key_file(os.path.join(root, 'id_rsa'))
      
      # 定义通道,指定连接参数
      transport = paramiko.Transport(('192.168.10.202', 22))
      transport.connect(username='root', pkey=sec_key)
      
      # 创建链接
      sftp = paramiko.SFTPClient.from_transport(transport)
      
      # 传输文件,文件存在则覆盖,不存在则创建
      sftp.put('s1.py', '/usr/local/src/qiao1.py'# y一定要指定scp过去的文件名称,否则报错
      sftp.put('s1.py', '/usr/local/src/qiao2.py')
      transport.close()
      

  • 问题:
    • 对于执行命令可以使用ssh_obj ,也可以使用transport;但是对于上传文件,只能使用transport
    • 那么若需要执行N条命令后再传文件,然后再执行命令,则显然使用ssh_obj 的方式会不断创建链接(从ssh_obj.connect()执行命令到transport.connect()上传文件)
    • 即,最好均使用transport,将所有操作定义为一组操作,链接只需要创建一次,在这个链接上完成所有任务


原文地址:https://www.cnblogs.com/qiaogy/p/6295681.html