zoukankan      html  css  js  c++  java
  • paramiko模块

    1.模块作用

    通过ssh远程连接服务器并执行想要命令 类似于Xshell
    
    ansible批量管理机器,ansible底层用的就是paramiko模块

    2.使用

    1.安装

    pip3 install paramiko

    2.执行命令

    1.用户名和密码的方式
    #1.导入模块
    import paramiko
    
    #2.创建ssh对象
    ssh = paramiko.SSHClient()
    #3.允许链接不在know_hosts文件中主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    #4.链接服务器:地址,端口号,用户名,密码
    ssh.connect(hostname='0.0.0.0',port=3306,username='root',password='123')
    
    # 5.执行命令:
    stdin, stdout, stderr = ssh.exec_command('ip a')
    
    # 6.获取结果
    res = stdout.read()  # 基于网络传输 该结果是一个bytes类型
    print(res.decode('utf-8'))
    
    # 7.断开链接
    ssh.close()
    
    
    2.公钥和私钥(先讲公钥保存到服务器上)
    #1.导入模块
    import paramiko #2. 读取本地私钥:a.txt为文件路径 private_key = paramiko.RSAKey.from_private_key_file('a.txt') # 3.创建SSH对象 ssh = paramiko.SSHClient() # 4.允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 5.连接服务器 ssh.connect(hostname='0.0.0.0', port=22, username='root', pkey=private_key) # 6.执行命令 stdin, stdout, stderr = ssh.exec_command('ls /') # 7.获取命令结果 result = stdout.read() print(result.decode('utf-8')) # 8.关闭连接 ssh.close()

    3.上传和下载文件

    1.#用户名密码方式
    import paramiko
    
    #2.ip端口 用户名和密码
    transport = paramiko.Transport(('172.16.219.168', 22))
    transport.connect(username='root', password='jason123')
    
    sftp = paramiko.SFTPClient.from_transport(transport)
    
    # 3.上传文件:本地文件,上传后位置路径
    sftp.put("a.txt", '/data/tmp.txt')  # 注意上传文件到远程某个文件下 文件必须存在
    
    #4.下载文件:服务器文件,本地路径
    sftp.get('/data/tmp.txt', 'hahahha.txt')  # 将远程文件下载到本地并重新命令
    #5.关闭链接
    transport.close() 2.# 公钥私钥方式 import paramiko #1.链接 private_key = paramiko.RSAKey.from_private_key_file('a.txt') transport = paramiko.Transport(('172.16.219.168', 22)) transport.connect(username='root', pkey=private_key) sftp = paramiko.SFTPClient.from_transport(transport) # 2.将location.py 上传至服务器 /tmp/test.py sftp.put('/tmp/location.py', '/tmp/test.py') # 3.将remove_path 下载到本地 local_path sftp.get('remove_path', 'local_path') transport.close()

    4.封装总结

    秘钥和用户名密码的区别在于链接时参数的不同而已:
    1.密码
    ssh.connect(hostname='0.0.0.0',port=3306,username='root',password='123')
    2.秘钥
    ssh.connect(hostname='0.0.0.0', port=22, username='root', pkey=private_key)
    文件上传下载同理
    transport.connect(username='root', password='123')
    transport.connect(username='root', pkey=private_key)

    疑问点:如果我想链接服务器执行多条命令并且还想上传下载文件,那么你所能看到的一般做法都是执行一次命令创建一次链接

    我们要实现在一个链接上即可以执行命令又可以上传下载文件

    我们封装成一个类,类的内部有一系列的方法,并且这些方法都可以在同一个链接下执行多次

    # 1.基于用户名密码使用封装
    import paramiko
    
    class SSHProxy(object):
        def __init__(self, hostname, port, username, password):
            self.hostname = hostname
            self.port = port
            self.username = username
            self.password = password
            self.transport = None
    
        def open(self):  # 给对象赋值一个上传下载文件对象连接
            self.transport = paramiko.Transport((self.hostname, self.port))
            self.transport.connect(username=self.username, password=self.password)
    
        def command(self, cmd):  # 正常执行命令的连接  至此对象内容就既有执行命令的连接又有上传下载链接
            ssh = paramiko.SSHClient()
            ssh._transport = self.transport
    
            stdin, stdout, stderr = ssh.exec_command(cmd)
            result = stdout.read()
            return result
    
        def upload(self, local_path, remote_path):
            sftp = paramiko.SFTPClient.from_transport(self.transport)
            sftp.put(local_path, remote_path)
            sftp.close()
    
        def close(self):
            self.transport.close()
    
        def __enter__(self):
            print('with开始')
            self.open()
            return self  # 该方法返回什么 with ... as 后面就拿到什么
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('with结束')
            self.close()
    
    
    if __name__ == '__main__':
    #1. with上下文管理使用(推荐) obj = SSHProxy(hostname='172.16.219.168',port=22,username='root',password='jason123') with obj as ssh: # 默认不支持 对象执行with会自动触发内部的__enter__方法 print('with内部代码')
    # with上下文执行完毕之后 会自动触发__exit__方法

    #2.使用方式2:

    #2.尝试基于用户名密码秘钥封装

    mport paramiko
    
    class SSHProxy(object):
        def __init__(self, hostname, port, username, password,pkey):
            self.hostname = hostname
            self.port = port
            self.username = username
            self.password = None
            self.pkey = None
            self.transport = None
    
        def open(self):  # 给对象赋值一个上传下载文件对象连接
            self.transport = paramiko.Transport((self.hostname, self.port))
            self.transport.connect(username=self.username, password=self.password,pkey=self.pkey)
    
        def command(self, cmd):  # 正常执行命令的连接  至此对象内容就既有执行命令的连接又有上传下载链接
            ssh = paramiko.SSHClient()
            ssh._transport = self.transport
    
            stdin, stdout, stderr = ssh.exec_command(cmd)
            result = stdout.read()
            return result
    
        def upload(self, local_path, remote_path):
            sftp = paramiko.SFTPClient.from_transport(self.transport)
            sftp.put(local_path, remote_path)
            sftp.close()
        def down(self,remote_path,local_path):
            sftp = paramiko.SFTPClient.from_transport(self.transport)
            sftp.get(remote_path,local_path)
            sftp.close()
    
        def close(self):
            self.transport.close()
    
        def __enter__(self):
            print('with开始')
            self.open()
            return self  # 该方法返回什么 with ... as 后面就拿到什么
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('with结束')
            self.close()
  • 相关阅读:
    ios10兼容问题
    safari图片跨域
    出现Unable to locate appropriate constructor on class 错误可能的原因
    localStorage、sessionStorage用法以及区别
    多行文本垂直居中,多行文本溢出
    【汉字】转【pīnyīn】
    移除行块级元素之间的空格(译文)
    jquery插件——检测DOM元素是否在浏览器可视范围之内
    监控阮一峰老师的blog
    PHP实现linux命令tail -f
  • 原文地址:https://www.cnblogs.com/tfzz/p/13183403.html
Copyright © 2011-2022 走看看