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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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