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()
相关推荐
SKYDROID云卓小助手2 小时前
三轴云台之相机技术篇
运维·服务器·网络·数码相机·音视频
东方佑2 小时前
自动调整PPT文本框内容:防止溢出并智能截断文本
linux·运维·powerpoint
泥土编程4 小时前
kubekey -实现懒人一键部署K8S集群
linux·运维
wirepuller_king7 小时前
创建Linux虚拟环境并远程连接,finalshell自定义壁纸
linux·运维·服务器
在野靡生.7 小时前
Ansible(1)—— Ansible 概述
linux·运维·ansible
风123456789~7 小时前
【Linux运维】查询指定日期的上月
linux·运维·服务器
zyk_5208 小时前
Docker desktop如何汉化
运维·docker·容器
韭菜盖饭8 小时前
解决Docker端口映射后外网无法访问的问题
运维·docker·容器
CC.cc.9 小时前
Linux系统之systemctl管理服务及编译安装配置文件安装实现systemctl管理服务
linux·运维·服务器
CZIDC9 小时前
win11 系统环境下 新安装 WSL ubuntu + ssh + gnome 桌面环境
数据库·ubuntu·ssh