本地连接环境代码详解

SSH连接主机

目的

使用python实现ssh连接特定主机,可以发送命令和接收命令回显,并具备日志功能。

需求

根据目的可分解为4个需求

  1. ssh连接特定主机
  2. 发送命令
  3. 回显命令—处理输出以及异常
  4. 日志功能

实现

Ssh.py

维护一个Ssh类

import paramiko
from lib.common.Logger import Logger
import time
import re

class ClassCli:
    def __init__(self, ip: str, username: str, passwd: str):
        self.ip = ip
        self.username = username
        self.passwd = passwd
        self.SSHConnect = self.__connect()
        self.logger = Logger(self.__class__.__name__)
        self.shell = None

    def __connect(self):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # 自动添加主机密钥
        ssh.connect(self.ip, username=self.username, password=self.passwd)
        return ssh


    def open_shell(self):
        # 模拟交互式终端
        self.shell = self.SSHConnect.invoke_shell()
        time.sleep(1)  # 等待终端初始化完成

        # 读取并记录登录信息
        login_info = ""
        while self.shell.recv_ready():
            login_info += self.shell.recv(1024).decode('utf-8', 'ignore')
        self.logger.info("Login Information:\n" + login_info)

    def exec_command(self, cmd: str, waitstr: str = r'[#$]', timeout: int = 10):
        if not self.shell:
            self.open_shell()  # 如果shell未创建,则创建并记录登录信息

        # 发送命令
        self.shell.send(f"{cmd}\n")
        # 等待特定字符串出现
        start_time = time.time()
        output = ""
        while True:
            if self.shell.recv_ready():
                output += self.shell.recv(1024).decode('utf-8', 'ignore')
                if re.search(waitstr, output):
                    break
            if time.time() - start_time > timeout:
                raise TimeoutError(f"Command execution timed out after {timeout} seconds")
            time.sleep(0.1)  # 稍作等待,避免CPU占用过高

        self.logger.info(output)
        return output

    def close(self):
        # 关闭SSH连接
        self.SSHConnect.close()

Logger.py

通过logging库建立一个日志记录器

import logging

class Logger:
    def  __init__(self, __name__):
        # 获取日志记录器
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        # 获取控制台处理器
        self.handler = logging.StreamHandler()
        self.handler.setLevel(logging.DEBUG)
        self.formatter = logging.Formatter('[%(levelname)s]:%(asctime)s - %(filename)s:%(lineno)s: %(message)s')
        self.handler.setFormatter(self.formatter)
        self.logger.addHandler(self.handler)
        pass

    def info(self, str):
        return self.logger.info(str)
    
    def error(self, str):
        return self.logger.error(str)

    def debug(self, str):
        return self.logger.debug(str)    

main.py

测试

from Logger import Logger
from Ssh  import ClassCli

logger = Logger(__name__)

node = ClassCli("192.168.137.131", "root", "123456")
node.exec_command("ls")
logger.info("cmd is : ls")
logger.error("cmd is : ls")
logger.debug("cmd is : ls")
node.close()
posted @ 2025-06-25 23:11  LemHou  阅读(9)  评论(0)    收藏  举报