#!/usr/bin/python3 # coding: utf-8 """ author: 猪猪侠 https://github.com/ring04h """ import logging import subprocess logging.basicConfig(level=logging.DEBUG) # # (crontab -l;echo '0 2 * * * /usr/local/bin/python3 /data/script/zombie_clean.py') | crontab - # import logging import subprocess # 判断是否超时的函数 def is_timeout(etime): """ 判断进程的运行时间是否超时。 参数: etime (str):进程的运行时间字符串,格式可能为 "天数-小时数" 或直接是小时数。 返回: bool:如果天数大于等于 1 或者小时数超过一定阈值(这里没有具体指定阈值),返回 True,表示超时;否则返回 False。 """ if '-' in etime: day, hour = etime.split('-') return True if int(day) >= 1 else False else: return False # 执行命令的函数 def cmdprocess(cmdline): """ 执行给定的命令行。 参数: cmdline (str):要执行的命令行字符串。 返回: tuple:包含命令的标准输出、标准错误输出和返回码。 """ # 使用 subprocess.Popen 执行命令,捕获标准输出和标准错误输出 pipe = subprocess.Popen(cmdline, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 等待命令执行完成,获取标准输出和标准错误输出 output, stderr = pipe.communicate() # 获取命令的返回码 return_code = pipe.returncode # 将标准错误输出解码为字符串 stderr = stderr.decode(errors='replace') # 将标准输出解码为字符串 output = output.decode(errors='replace') return output, stderr, return_code def main(): # 构建查找 crawlergo 进程 ID 的命令行 cmdline = "ps -ef | grep crawlergo | grep -v grep | awk '{print $2}'" # 执行命令,获取输出、错误输出和返回码 output, stderr, return_code = cmdprocess(cmdline) # 如果返回码不为 0,表示命令执行失败,直接返回 if return_code!= 0: return # 将输出的进程 ID 按行分割成列表 zombie_pids = output.splitlines() # 遍历每个 crawlergo 的进程 ID for zombie_pid in zombie_pids: # 构建查找指定进程 ID 的运行时间的命令行 cmdline = f'''ps -eo pid,etime | grep {zombie_pid}''' # 执行命令,获取输出、错误输出和返回码 ps_output, ps_stderr, ps_return_code = cmdprocess(cmdline) # 如果返回码不为 0,表示命令执行失败,继续下一个进程 ID 的处理 if ps_return_code!= 0: continue # 遍历输出的每一行(包含进程 ID 和运行时间) for line in ps_output.splitlines(): # 将每行按空格分割,获取进程 ID 和运行时间 pid, etime = line.split() # 判断运行时间是否超时 status = is_timeout(etime) # 打印调试信息,包括进程 ID、运行时间和是否超时 logging.debug(f"PID: {pid:<8} ETIME: {etime:<15} TIMEOUT: {status}") # 如果没有超时,继续下一个进程 ID 的处理 if not status: continue # 构建杀死进程的命令行 kill_cmdline = f"kill -9 {pid}" # 打印调试信息,表示要执行的杀死进程的命令 logging.debug(f"call kill : [{kill_cmdline}]") # 执行杀死进程的命令 cmdprocess(kill_cmdline) if __name__ == "__main__": main()