#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import csv import paramiko import re # ====================== 基础配置 ====================== IP_FILE = "ip.txt" SSH_USER = "root" SSH_PASS = "hp93000" SSH_TIMEOUT = 3 # ====================================================== def print_help(): help_text = """ 用法:python check_proc.py 进程名称 示例: python check_proc.py trap python check_proc.py node_exporter python check_proc.py nginx python check_proc.py redis """ print(help_text) sys.exit(1) def clean_ip_file(filepath): """清洗ip.txt:去除\r、空行、首尾空格""" clean_ips = [] with open(filepath, "r", encoding="utf-8") as f: for line in f: line = line.replace("\r", "").strip() if line: clean_ips.append(line) return clean_ips def judge_ip_type(ip): """判断IPv4 / IPv6""" if ":" in ip: return "IPv6" return "IPv4" def ssh_check_host(ip, proc_name, timeout): """SSH连接远程主机,获取主机名、系统版本、进程数量""" client = paramiko.SSHClient() # 自动信任主机密钥,等同Shell StrictHostKeyChecking=no client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect( hostname=ip, username=SSH_USER, password=SSH_PASS, timeout=timeout, banner_timeout=timeout ) # 远程执行命令,和原Shell命令完全一致 remote_cmd = f""" hostname cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 | head -n1 ps -ef | grep -v grep | grep -i '{proc_name}' | wc -l """.strip() stdin, stdout, stderr = client.exec_command(remote_cmd) output = stdout.read().decode("utf-8", errors="ignore").strip() err = stderr.read().decode("utf-8", errors="ignore") client.close() if not output: return {"hn": "命令无输出", "os": "---", "status": "未知"} lines = [line.strip() for line in output.splitlines() if line.strip()] hn = lines[0] if len(lines) >= 1 else "获取失败" os_ver = lines[1] if len(lines) >= 2 else "获取失败" proc_count = lines[2] if len(lines) >= 3 else "0" try: cnt = int(proc_count) except ValueError: cnt = 0 if cnt >= 1: status = "已运行" else: status = "未运行" return {"hn": hn, "os": os_ver, "status": status} except paramiko.NoValidConnectionsError: return {"hn": "连接失败", "os": "---", "status": "不可达"} except paramiko.AuthenticationException: return {"hn": "密码错误", "os": "---", "status": "认证失败"} except paramiko.socket.timeout: return {"hn": "SSH超时", "os": "---", "status": "超时"} except Exception as e: return {"hn": f"异常:{str(e)}", "os": "---", "status": "异常"} def main(): # 读取入参进程名 if len(sys.argv) != 2: print_help() target_proc = sys.argv[1].strip() csv_name = f"进程检查结果_{target_proc}.csv" # 清洗IP列表 ip_list = clean_ip_file(IP_FILE) total_ip = len(ip_list) print(f"===== 开始批量检查【进程:{target_proc}】=====") print(f"待检测IP总数:{total_ip}\n") # 初始化CSV写入 with open(csv_name, "w", encoding="utf-8-sig", newline="") as csv_f: writer = csv.writer(csv_f) # 表头,utf-8-sig保证Excel中文不乱码 writer.writerow(["IP地址", "IP类型", "主机名", "系统版本", "进程状态"]) for ip in ip_list: ip_type = judge_ip_type(ip) print(f"→ {ip}", end=" ") res = ssh_check_host(ip, target_proc, SSH_TIMEOUT) hn = res["hn"] os_v = res["os"] st = res["status"] print(f" [{st}]") writer.writerow([ip, ip_type, hn, os_v, st]) print(f"\n===== 执行完成 =====") print(f"报告文件:{csv_name}") print(f"查询进程:{target_proc}") print(f"总检测IP数量:{total_ip}") if __name__ == "__main__": main()