Python 使用Paramiko的SSHClient以命令行方式实现数据库操作

一、Python的远程控制模块Paramiko

  Paramiko是python的一个库,它实现了SSHv2协议,通过Paramiko可以在Python中直接使用SSH协议对远程服务器执行操作

1. Paramiko的两个核心组件:SSHClient和SFTPClient

  • SSHClient是对SSH会话的封装,通常用于执行远程命令
  • SFTPClient是对SFTP客户端的封装,通常用于实现远程文件操作

2. Paramiko的基础名词

  • Channel:类Socket,一种安全的传输通道
  • Transport:加密会话,使用时会创建一个加密的Tunnels(即Channel)
  • Session:是client与Server保持连接的对象

3. Paramiko的基本使用方法

(1)connect(): 实现远程服务器的连接与认证,只有hostname是必传参数

 常用参数

  • hostname 连接的目标主机
  • port=SSH_PORT 指定端口
  • username=None 验证的用户名
  • password=None 验证的用户密码
  • pkey=None 私钥方式用于身份验证
  • key_filename=None 一个文件名或文件列表,指定私钥文件
  • timeout=None 可选的tcp连接超时时间
  • allow_agent=True, 是否允许连接到ssh代理,默认为True 允许l
  • ook_for_keys=True 是否在~/.ssh中搜索私钥文件,默认为True 允许
  • compress=False, 是否打开压缩

(2)set_missing_host_key_policy():设置远程服务器没有在know_hosts文件中记录时的应对策略,目前支持三种:

  • AutoAddPolicy:自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置,即新建立ssh连接时不需要再输入yes或no进行确认
  • WarningPolicy:用于记录一个未知的主机密钥的Python警告,并接受,会提示是新连接
  • RejectPolicy:自动拒绝未知的主机名及密钥,依赖load_system_host_key的配置。此为默认选项

(3)exec_command():在远程服务器上执行Linux命令, 使用ssh exec channel

(4)invoke_shell():交互式执行操作,使用ssh shell channel

(5)open_sftp():在当前ssh会话基础上创建一个sftp会话,该方法返回一个SFTPClient对象

 二、paramiko远程密码连接,交互式执行操作命令

   实现远程操作sqlite数据库

# -*- coding: utf-8 -*-

import time
import socket

import paramiko
from paramiko.channel import PipeTimeout

BUFFER_SIZE = 4 * 1024 * 1024

class Base:
    def __init__(self, hostname, username, password, port=22):
        s = paramiko.SSHClient()    # 创建ssh对象
        s.set_missing_host_key_policy(paramiko.WarningPolicy)   # 链接的远程主机没有本地主机密钥或HostKeys对象时的策略
        s.connect(hostname, port, username, password)
        self.sshclient = s
        self.shell = s.invoke_shell()   # 启动命令行输入命令
        self.shell.setblocking(False)   # 设置非阻塞
        self._clear()   # 清行 回车

    def __del__(self):
        self.shell.close()
        self.sshclient.close()

    def delete(self):
        self.__del__()

    def _clear(self):
        try:
            self.shell.send('\n')
            self.shell.recv(BUFFER_SIZE)
        except (PipeTimeout, socket.timeout):
            pass

    def send_wait_recv(self, msg, waittime=1):
        if not msg.endswith('\n'):
            msg += '\n'     # 给命令添加回车 使其执行
        self.shell.send(msg)  # 执行命令
        time.sleep(waittime)
        try:
            return self.shell.recv(BUFFER_SIZE).decode(errors='replace')
        except (PipeTimeout, socket.timeout):
            return None

    def connect_to_db(self, db_path'):
        print(self.send_wait_recv('sqlite3 {}'.format(db_path)))

 执行查询操作

b = Base(hostname, username, password)
b.connect_to_db()
print(b.send_wait_recv("select * from dbtable where str=''  limit 10;"))

 

  

posted @ 2020-11-12 13:21  薄小木的自动化进阶之路  阅读(2121)  评论(0)    收藏  举报