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()
相关推荐
大鹅同志18 分钟前
在服务器上开Juypter Lab教程(远程访问)
运维·服务器·pytorch·jupyter·cuda·云服务器
文牧之38 分钟前
PostgreSQL的walsender和walreceiver进程介绍
运维·数据库·postgresql
炸裂狸花猫1 小时前
Linux技术04-IPVS
linux·运维·服务器
快快小毛毛1 小时前
CC攻击防御策略要怎么调整?使用游戏盾有效解决
运维·服务器·网络·tcp/ip·游戏·udp
ʚɞ4961 小时前
k8s环境下的相关操作
运维·excel
J老熊1 小时前
Linux下抓包分析Java应用程序HTTP接口调用:基于tcpdump与Wireshark的综合示例
java·linux·运维·web安全·http·面试
库库的里昂3 小时前
【Linux修行路】网络套接字编程——UDP
linux·运维·服务器·网络·udp
Wang201220133 小时前
ubuntu下手工编译安装 6.* 最新内核
linux·运维·ubuntu
不见长安见晨雾4 小时前
Linux:RPM软件包管理以及Yum软件包仓库
linux·运维·服务器
专家大圣4 小时前
Linux 信息安全:构建坚固的防御体系
linux·运维·服务器