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()
相关推荐
自由鬼几秒前
开源漏洞扫描器:OpenVAS
运维·服务器·安全·网络安全·开源·漏洞管理
難釋懷2 分钟前
Shell脚本-while循环语法结构
linux·运维·服务器·bash
B64A-消闲19 分钟前
shell命令一
linux·运维
明·煜28 分钟前
解决VSCode每次SSH连接服务器时,都需要下载vscode-server
ide·vscode·ssh
難釋懷1 小时前
Shell脚本-for循环应用案例
linux·运维·服务器·bash
昊昊昊昊昊明2 小时前
10天学会嵌入式技术之51单片机-day-7
linux·运维·网络
Sonetto19992 小时前
Nginx 反向代理,啥是“反向代理“啊,为啥叫“反向“代理?而不叫“正向”代理?它能干哈?
运维·前端·nginx
达斯维达的大眼睛2 小时前
如何在Linux用libevent写一个聊天服务器
linux·运维·服务器·网络
末央&2 小时前
【Linux】gdb工具,Linux 下程序调试的 “透视眼”
linux·运维·服务器
珹洺2 小时前
Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互
java·运维·前端·mysql·intellij-idea·jsp