You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiaCTFer/client-1/urlscan/xray/zombie_clean.py

110 lines
3.5 KiB

2 months ago
#!/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()