Python_paramiko_与linux交互

一、基础功能介绍 

# coding=utf-8
import paramiko
from time import sleep

# 建立通信
transport = paramiko.Transport(('192.168.0.7', 22))
print(transport)  # <paramiko.Transport at 0x5745ed0 (unconnected)>

# 建立连接
transport.connect(username='root', password='123456')
print(transport)  # <paramiko.Transport at 0x5745ed0 (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>
# 注意 active 此时为0

# 开启一个信道
channel = transport.open_session()
print(channel)  # <paramiko.Channel 0 (open) window=0 -> <paramiko.Transport at 0x5745ed0 (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>
# 调用open_session后,active为1,表示已打开channel。此时只能下发命令,收不到回显

# 设置信道获取信息的超时时间。因为在调用 channel.recv(65535) 方法时 会阻塞执行,不设置就会卡死。
channel.timeout = 10

# 开启终端,进入交互模式
channel.get_pty()
channel.invoke_shell()

sleep(2)  # 是为了一次能显示完所有回显,如果不等待2秒,获取的回显可能不完整。

# 检查通道是否有数据。若没有,则返回False,注意:不能用来判断已回显完。当下发命令后,执行出现卡顿,在卡顿期间信道是没有数据的。
channelStatus = channel.recv_ready()
print(channelStatus)  # 此时返回True

# 获取返回的数据。此时返回的是登陆信息。注意:当信道没有数据是,若直接获取,则会处于阻塞状态
backMsg = channel.recv(65535).decode('utf-8')  # 使用recv读取in-buffer内容,65535表示预读取内容大小,若该值小于in-buffer值,则会读取不完全
print(backMsg)

# 下发命令,命令后需追加\n表示发送命令
channel.send("10.27.0.7 \r")
sleep(2)
backMsg = channel.recv(65535).decode('utf-8')
print(backMsg)

channel.send("mysql22001  \r")
sleep(2)
backMsg = channel.recv(65535).decode('utf-8')
print(backMsg)

channel.send("quit;  \r")
sleep(2)
backMsg = channel.recv(65535).decode('utf-8')
print(backMsg)

# 关闭信道
channel.close()

# 关闭连接
transport.close()

二、简单封装

import paramiko
import time


class SSH(object):

    def __init__(self):
        self.__transport = None
        self.__channel = None
        self.__default_end_check_infos = ["[root@"]

    def connect(self, host, port, username, password, **kwargs):
        # 建立通信
        self.__transport = paramiko.Transport((host, port))

        # 建立连接
        self.__transport.connect(username=username, password=password)

        # 开启一个信道
        self.__channel = self.__transport.open_session()
        self.__channel.timeout = 10

        # 开启终端,进入交互模式
        self.__channel.get_pty()
        self.__channel.invoke_shell()
        return self.__echo(**kwargs)

    def disconnect(self):
        self.__channel.close()
        self.__transport.close()

    def exec_cmd(self, cmd, **kwargs):
        self.__channel.send("%s \r" % cmd)
        return self.__echo(**kwargs)

    def set_echo_end_check_info(self, end_check_info=None):
        """ 设置回显校验信息 """
        if end_check_info is not None:
            if isinstance(end_check_info, str):
                self.__default_end_check_infos.append(end_check_info)
            if isinstance(end_check_info, list):
                self.__default_end_check_infos = self.__default_end_check_infos + end_check_info
        return self.__default_end_check_infos

    def __echo(self, timeout=10, interval=0.5):
        """ 获取回显 """
        t0 = time.time()
        echo = ""
        while time.time()-t0 < timeout:
            if self.__channel.recv_ready() is True:
                _echo = self.__channel.recv(65535).decode('utf-8')
                echo += _echo
                for end_check_info in self.__default_end_check_infos:
                    if end_check_info in echo:
                        print(echo)
                        time.sleep(0.5)
                        return echo
            time.sleep(interval)
        self.disconnect()
        raise RuntimeError("获取预期回显超时!")


if __name__ == '__main__':
    ssh_session = SSH()
    ssh_session.set_echo_end_check_info(["Opt>"])
    ssh_session.set_echo_end_check_info("MySQL")
    ssh_session.connect('192.168.0.7', 22, 'root', '123456')
    ssh_session.exec_cmd("10.27.0.7")
    ssh_session.exec_cmd("mysql22001")
    ssh_session.exec_cmd("quit;")
    ssh_session.disconnect()

执行结果:

 

posted @ 2019-11-01 11:07  码上测  阅读(2167)  评论(0编辑  收藏  举报