31.python ssh执行远程代码,并实时获取日志

paramiko

应用场景

在一些系统开发中,需要远程到linux机器执行某个任务。我们的要求是:

  1. 实时获取执行日志
  2. 生命周期一致,意思是,后端服务如果挂了,linux任务也得自动挂掉,防止僵尸进程
  3. 如何判断任务的状态,因为实时收集日志,因此可以在linux放一个封装好的执行脚本,
    脚本做好异常捕捉,这样后端可通过关键字匹配任务是否失败,除了失败就是成功。且后端采集日志的
    代码是while True 的样式,不断尝试获取一定字节的日志。 当未跳出while True期间任务状态就是running

代码

python 复制代码
import io
import json
import traceback
import paramiko

class LinuxCMDClient(object):

    def __init__(self, ip, port, username, password):
        self.ssh = paramiko.SSHClient()
        self.establish = False
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
        self.sftp = None
    # ssh建立和linux的连接
    def connect(self, timeout=15):
        # 创建SSHClient实例对象
        try:
            print("[ETL] [LinuxCMDClient] Attempt to establish a connection.")
            # 调用方法,标识没有远程机器的公钥,允许访问
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # 连接远程机器 地址端口用户名密码
            self.ssh.connect(self.ip, self.port, self.username, self.password, timeout=timeout)
            self.establish = True

        except Exception as e:
            print("[LinuxCMDClient] {ip=%s,port=%s,user=%s,password=%s}, error=%s" %(self.ip,
                                                                                            self.port,
                                                                                            self.username,
                                                                                            self.password,
                                                                                            traceback.format_exc())
                         )
            if self.ssh:
                self.ssh.close()

    # 执行linux命令
    def exec_cmd(self, cmds,path):
        print("[ETL] [LinuxCMDClient]  exec cmd=%s" % cmds)
        if self.establish is False:
            self.connect()
        stdin, stdout, stderr = self.ssh.exec_command(cmds, get_pty=True)
        with open(path, "a+", encoding="utf-8") as f:
            while True:
                msg = stdout.channel.recv(1024).decode()
                if msg is "":
                    f.write("执行结束")
                    break
                else:
                    f.write(msg.replace("\n", ""))

    # __del__ 魔法函数用于对象销毁之后的资源回收,此处十分有效,不需要手动调用,此函数是自发行为
    def __del__(self):
        if self.ssh:
            self.ssh.close()
相关推荐
Avan_菜菜8 小时前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB1 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode3 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220703 天前
如何搭建本地yum源(上)
运维
大树886 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
开发者联盟league6 天前
安装pnpm
ssh
Inhand陈工6 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智6 天前
ARP代理--工作原理
运维·网络·arp·arp代理