zoukankan      html  css  js  c++  java
  • paramiko入门1

    paramiko

    该模块基于SSH用于连接远程服务器:

    安装:

    pip3 install paramiko

    SSHClient

    基于用户名密码连接并执行命令:

    import paramiko
    
    # 创建SSH对象
    ssh = paramiko.SSHClient() # 实例化
    
    # 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # 连接服务器
    ssh.connect(hostname='192.168.1.3', port=22, username='root', password='xxx')
    
    # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 获取命令结果
    
    res, err = stdout.read(), stderr.read()
    result = res if res else err
    print(result.decode())
    # 关闭连接 ssh.close()

     基于用户名密码上传下载:

    import paramiko
    
    transport = paramiko.Transport(("192.168.33.3", 22))
    transport.connect(username='root', password='xxx') # 进行连接
    
    sftp = paramiko.SFTPClient.from_transport(transport)
    # 将E:	esta.mp4'上传至服务器 /tmp/a.mp4
    sftp.put(r'E:	esta.mp4', '/tmp/a.mp4')
    # 将remove_path 下载到本地 local_path
    # sftp.get('remove_path', 'local_path')
    
    transport.close()

    基于公钥密钥连接:

    就是利用公钥和私钥进行验证,这里我们假设有2台机器(A/B)首先在A机器需要生成一个密钥对(公钥/私钥),然后把公钥传到B机器上,那么A访问B的时候,就可以不使用密码验证了

    基于公钥连接并执行命令:

    import paramiko
    
    # 私钥路径
    private_key = paramiko.RSAKey.from_private_key_file('id_rsa')
    
    # 创建SSH对象
    ssh = paramiko.SSHClient()
    
    # 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # 连接服务器
    ssh.connect(hostname='192.168.33.3', port=22, username='test', pkey=private_key)
    
    # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 获取命令结果
    result = stdout.read()
    print(result.decode())
    # 关闭连接
    ssh.close()

     基于密钥上传下载:

    import paramiko
    
    private_key = paramiko.RSAKey.from_private_key_file('id_rsa')
    
    transport = paramiko.Transport(('192.168.33.34', 22))
    transport.connect(username='test', pkey=private_key)
    
    sftp = paramiko.SFTPClient.from_transport(transport)
    # 将location.py 上传至服务器 /tmp/test.py
    sftp.put(r'E:	esta.mp4', '/tmp/b.mp4')
    # 将remove_path 下载到本地 local_path
    # sftp.get('remove_path', 'local_path')
    
    transport.close()

    基于transport用户名和密码连接并执行命令

    import paramiko
    
    transport = paramiko.Transport(('192.168.33.35', 22))
    transport.connect(username='root', password='xxx')
    
    ssh = paramiko.SSHClient()
    ssh._transport = transport
    
    stdin, stdout, stderr = ssh.exec_command('df')
    print(stdout.read().decode())
    
    transport.close()

    总结:

    1、执行命令既可以用SSHClient,也可以用transport

    2、当上传文件或下载文件的时候,只能用transport

    基于类的模式封装了命令和上传及下载功能

    import paramiko
    
    
    class SSH:
        def __init__(self, host, port, user, pwd):
            self.host = host
            self.port = port
            self.user = user
            self.pwd = pwd
            self.transport = None
    
        def connect(self):
            self.transport = paramiko.Transport((self.host, self.port))
            self.transport.connect(username=self.user, password=self.pwd)  # 进行连接
    
        def cmd(self, cmd):
            ssh = paramiko.SSHClient()
            ssh._transport = self.transport
            stdin, stdout, stderr = ssh.exec_command(cmd)
            return stdout.read()
    
        def download(self, server_path, local_path):
            sftp = paramiko.SFTPClient.from_transport(self.transport)
            sftp.get(server_path, local_path)
    
        def upload(self, local_path, server_path):
            sftp = paramiko.SFTPClient.from_transport(self.transport)
            sftp.put(local_path, server_path)
    
        def close(self):
            self.transport.close()
    
    
    obj = SSH('192.168.33.35', 22, 'root', 'xxx')
    obj.connect()
    a = obj.cmd('ls')
    print(a.decode())
    b = obj.cmd('df')
    print(b.decode())
    obj.close()

    第三种连接方式:保持会话

    前面我们介绍了用户名密码和使用transport方式,下面介绍来介绍第三种方式:保持会话,从方法主要适合开发堡垒机环境。

    paramiko模块保持会话连接(一):

    不适用于windows环境,需要在linux环境运行。

    import paramiko
    import sys
    import socket
    import select
    from paramiko.py3compat import u
    
    tran = paramiko.Transport(('192.168.33.35', 22,))
    tran.start_client()
    tran.auth_password('root', 'redhat')
    
    # 打开一个通道
    chan = tran.open_session()
    # 获取一个终端
    chan.get_pty()
    # 激活器
    chan.invoke_shell()
    
    while True:
        # 监视用户输入和服务器返回数据
        # sys.stdin 处理用户输入
        # chan 是之前创建的通道,用于接收服务器返回信息
        readable, writeable, error = select.select([chan, sys.stdin, ], [], [], 1)
        if chan in readable:
            try:
                x = u(chan.recv(1024))  # u代表paramiko的兼容模式,在py3中需要
                if len(x) == 0:
                    print('
    *** EOF
    ')
                    break
                sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in readable:
            inp = sys.stdin.readline()  # readline表示读一整行
            chan.sendall(inp)
    
    chan.close()
    tran.close()

    paramiko模块保持会话连接(二):

    import paramiko
    import sys
    import socket
    import select
    import termios
    import tty
    from paramiko.py3compat import u
    
    tran = paramiko.Transport(('192.168.33.35', 22,))
    tran.start_client()
    tran.auth_password('root', 'redhat')
    
    # 打开一个通道
    chan = tran.open_session()
    # 获取一个终端
    chan.get_pty()
    # 激活器
    chan.invoke_shell()
    
    # 获取原tty属性
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        # 为tty设置新属性
        # 默认当前tty设备属性:
        #   输入一行回车,执行
        #   CTRL+C 进程退出,遇到特殊字符,特殊处理。
    
        # 这是为原始模式,不认识所有特殊符号
        # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
        tty.setraw(sys.stdin.fileno())
        chan.settimeout(0.0)
    
        while True:
            # 监视 用户输入 和 远程服务器返回数据(socket)
            # 阻塞,直到句柄可读
            r, w, e = select.select([chan, sys.stdin], [], [], 1)
            if chan in r:
                try:
                    x = u(chan.recv(1024))
                    if len(x) == 0:
                        print('
    *** EOF
    ')
                        break
                    sys.stdout.write(x)
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                chan.send(x)
    
    finally:
        # 重新设置终端属性
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
    
    chan.close()
    tran.close()

    更多参见:paramoko源码 https://github.com/paramiko/paramiko

  • 相关阅读:
    Simple Automated Backups for MongoDB Replica Sets
    [转] matlab获取时间日期
    Matlab与C++混合编程 编写独立外部应用程序时出现“无法定位序数3906于动态链接库LIBEAY32.dll上”错误
    Visual Studio 控制台应用程序 同时使用OpenCV和matlab mat文件操作
    [转] Matlab与C++混合编程(依赖OpenCV)
    OpenCV 64位时 应用程序无法正常启动0x000007b 问题解决
    LinkedBlockingQueue多线程测试
    rdlc报告vs2008编辑正常,在vs2012在对错误的编辑
    SD3.0四个协议解读
    链队列
  • 原文地址:https://www.cnblogs.com/chen1930/p/6143961.html
Copyright © 2011-2022 走看看