From 82eeee50f13cf0483f69ac4d2dd8c17eca81fd53 Mon Sep 17 00:00:00 2001 From: UnbalancedCat Date: Fri, 3 Oct 2025 17:29:58 +0800 Subject: [PATCH] add linux support --- README_Ubuntu.md | 290 ++++++++++++++++++++++ deploy_system.sh | 528 ++++++++++++++++++++++++++++++++++++++++ manage.sh | 574 ++++++++++++++++++++++++++++++++++++++++++++ smart_shutdown.ps1 | 2 +- smart_shutdown.sh | 316 ++++++++++++++++++++++++ uninstall_system.sh | 223 +++++++++++++++++ 6 files changed, 1932 insertions(+), 1 deletion(-) create mode 100644 README_Ubuntu.md create mode 100755 deploy_system.sh create mode 100755 manage.sh create mode 100755 smart_shutdown.sh create mode 100755 uninstall_system.sh diff --git a/README_Ubuntu.md b/README_Ubuntu.md new file mode 100644 index 0000000..9db9a3c --- /dev/null +++ b/README_Ubuntu.md @@ -0,0 +1,290 @@ +# 智能网络监控脚本 - Ubuntu版本 + +## 📁 项目结构 + +``` +smart-shutdown/ +├── smart_shutdown.sh # 主监控脚本(用户模式) +├── deploy_system.sh # 系统级部署脚本 +├── uninstall_system.sh # 系统级卸载脚本 +├── manage.sh # 管理工具脚本 +├── README.md # 本文件 +└── logs/ # 本地运行时的日志目录 + └── network_monitor_YYYYMMDD.log +``` + +## 🚀 快速开始 + +### 系统级部署(推荐) + +```bash +# 1. 克隆或下载项目到本地 +cd /path/to/smart-shutdown/ + +# 2. 以root权限运行部署脚本 +sudo ./deploy_system.sh +``` + +**部署效果:** +- 程序文件:`/opt/smart-network-monitor/` +- 配置文件:`/etc/smart-network-monitor/config.json` +- 日志文件:`/var/log/smart-network-monitor/` +- systemd服务:`smart-network-monitor.service` +- 开机自启动,无需用户登录 + +### 用户级运行 + +```bash +# 以root权限直接运行(需要用户登录) +sudo ./smart_shutdown.sh +``` + +## 🎯 系统部署后的文件位置 + +### 程序文件位置 +``` +/opt/smart-network-monitor/ +├── smart_shutdown_system.sh # 系统优化版监控脚本 +└── manage.sh # 管理工具脚本 +``` + +### 配置文件位置 +``` +/etc/smart-network-monitor/ +└── config.json # 配置文件 +``` + +### 日志文件位置 +``` +/var/log/smart-network-monitor/ +└── network_monitor_YYYYMMDD.log # 日志文件 +``` + +## 🔧 管理命令 + +### 使用管理工具(推荐) +```bash +# 使用快捷命令(系统安装后可用) +smart-monitor + +# 或者直接运行管理脚本 +sudo /opt/smart-network-monitor/manage.sh +``` + +### 直接使用systemctl命令 + +#### 查看服务状态 +```bash +systemctl status smart-network-monitor +``` + +#### 启动/停止/重启服务 +```bash +sudo systemctl start smart-network-monitor +sudo systemctl stop smart-network-monitor +sudo systemctl restart smart-network-monitor +``` + +#### 启用/禁用开机自启动 +```bash +sudo systemctl enable smart-network-monitor +sudo systemctl disable smart-network-monitor +``` + +### 查看日志 + +#### 查看今天的应用日志 +```bash +cat /var/log/smart-network-monitor/network_monitor_$(date '+%Y%m%d').log +``` + +#### 实时监控应用日志 +```bash +tail -f /var/log/smart-network-monitor/network_monitor_$(date '+%Y%m%d').log +``` + +#### 查看系统日志 +```bash +# 查看最近的系统日志 +journalctl -u smart-network-monitor -n 50 + +# 实时监控系统日志 +journalctl -u smart-network-monitor -f +``` + +## ⚙️ 配置说明 + +系统部署后,配置文件位于:`/etc/smart-network-monitor/config.json` + +### 默认配置 +```json +{ + "TargetIP": "192.168.3.3", + "MonitorWindowSeconds": 180, + "ShutdownCountdown": 60, + "NormalPingInterval": 15 +} +``` + +### 配置参数说明 +- `TargetIP`: 监控的目标IP地址 +- `MonitorWindowSeconds`: 监控窗口时长(秒),网络持续中断超过此时间将触发关机 +- `ShutdownCountdown`: 关机倒计时时长(秒) +- `NormalPingInterval`: 正常监控时的ping间隔(秒) + +### 修改配置 +```bash +# 使用管理工具编辑(推荐) +smart-monitor + +# 或直接编辑配置文件 +sudo nano /etc/smart-network-monitor/config.json + +# 修改配置后重启服务使配置生效 +sudo systemctl restart smart-network-monitor +``` + +## 🗑️ 卸载 + +```bash +# 运行卸载脚本 +sudo ./uninstall_system.sh +``` + +卸载脚本会询问是否删除配置文件和日志文件,您可以选择保留或删除。 + +## 📊 功能特性 + +- ✅ 开机自启动,无需用户登录 +- ✅ 系统级权限运行 +- ✅ 智能日志管理(应用日志 + 系统日志) +- ✅ JSON配置文件支持 +- ✅ 自动日志清理(30天) +- ✅ 网络恢复自动取消关机 +- ✅ 完整的错误处理和信号处理 +- ✅ 彩色终端输出 +- ✅ 交互式管理工具 + +## 🔧 系统要求 + +### 必需软件包 +- `ping` (通常已预装) +- `systemctl` (systemd) +- `journalctl` (systemd) + +### 推荐软件包 +```bash +# 安装jq以获得更好的JSON配置支持 +sudo apt-get update +sudo apt-get install jq +``` + +### 支持的系统 +- Ubuntu 16.04+ (带systemd) +- Debian 8+ (带systemd) +- 其他使用systemd的Linux发行版 + +## 🔐 安全说明 + +- 脚本需要root权限以执行关机操作 +- systemd服务以root权限运行 +- 所有操作都会记录在应用日志和系统日志中 +- 支持通过systemd进行完整的服务管理和监控 + +## 📝 使用示例 + +### 1. 基本使用流程 + +```bash +# 1. 部署系统级服务 +sudo ./deploy_system.sh + +# 2. 检查服务状态 +systemctl status smart-network-monitor + +# 3. 查看实时日志 +journalctl -u smart-network-monitor -f + +# 4. 使用管理工具 +smart-monitor +``` + +### 2. 自定义配置示例 + +```bash +# 编辑配置文件 +sudo nano /etc/smart-network-monitor/config.json + +# 修改为监控路由器 +{ + "TargetIP": "192.168.1.1", + "MonitorWindowSeconds": 300, + "ShutdownCountdown": 120, + "NormalPingInterval": 30 +} + +# 重启服务应用配置 +sudo systemctl restart smart-network-monitor +``` + +### 3. 故障排除 + +```bash +# 查看服务详细状态 +systemctl status smart-network-monitor -l + +# 查看最近的错误日志 +journalctl -u smart-network-monitor --since "1 hour ago" + +# 测试网络连接 +ping -c 4 192.168.3.3 + +# 手动运行脚本进行调试 +sudo /opt/smart-network-monitor/smart_shutdown_system.sh +``` + +## 🚨 注意事项 + +1. **关机权限**:脚本需要root权限才能执行关机操作 +2. **网络依赖**:确保目标IP地址可达且稳定响应ping +3. **测试模式**:默认脚本在关机时会输出模拟信息,取消注释 `shutdown -h now` 行以启用实际关机 +4. **备份重要数据**:在启用实际关机功能前,请确保重要数据已备份 +5. **防火墙设置**:确保ICMP ping包不被防火墙阻挡 + +## 🔗 相关命令速查 + +```bash +# 服务管理 +sudo systemctl start smart-network-monitor # 启动 +sudo systemctl stop smart-network-monitor # 停止 +sudo systemctl restart smart-network-monitor # 重启 +sudo systemctl status smart-network-monitor # 状态 +sudo systemctl enable smart-network-monitor # 开机启动 +sudo systemctl disable smart-network-monitor # 禁用启动 + +# 日志查看 +journalctl -u smart-network-monitor # 所有日志 +journalctl -u smart-network-monitor -f # 实时日志 +journalctl -u smart-network-monitor -n 50 # 最近50行 +tail -f /var/log/smart-network-monitor/network_monitor_$(date '+%Y%m%d').log # 应用日志 + +# 配置管理 +sudo nano /etc/smart-network-monitor/config.json # 编辑配置 +cat /etc/smart-network-monitor/config.json # 查看配置 + +# 管理工具 +smart-monitor # 交互式管理 +``` + +## 📞 技术支持 + +如果您在使用过程中遇到问题,请: + +1. 检查系统日志:`journalctl -u smart-network-monitor -n 100` +2. 验证网络连接:`ping 目标IP` +3. 检查配置文件格式:`jq . /etc/smart-network-monitor/config.json` +4. 查看服务状态:`systemctl status smart-network-monitor -l` + +--- + +**享受智能网络监控带来的便利!** 🎉 \ No newline at end of file diff --git a/deploy_system.sh b/deploy_system.sh new file mode 100755 index 0000000..94ba8d4 --- /dev/null +++ b/deploy_system.sh @@ -0,0 +1,528 @@ +#!/bin/bash + +# +# 智能网络监控脚本 - Ubuntu系统级部署脚本 +# +# 功能描述: +# 将脚本部署到系统级目录,配置为systemd服务,开机自启动 +# +# 部署位置: +# - 程序文件: /opt/smart-network-monitor/ +# - 配置文件: /etc/smart-network-monitor/ +# - 日志文件: /var/log/smart-network-monitor/ +# - 服务文件: /etc/systemd/system/smart-network-monitor.service +# +# 使用方法: +# sudo ./deploy_system.sh +# + +# 设置颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +# 定义系统级路径 +PROGRAM_PATH="/opt/smart-network-monitor" +CONFIG_PATH="/etc/smart-network-monitor" +LOG_PATH="/var/log/smart-network-monitor" +SERVICE_FILE="/etc/systemd/system/smart-network-monitor.service" +SERVICE_NAME="smart-network-monitor" + +# 当前脚本目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +echo -e "${CYAN}==========================================${NC}" +echo -e "${CYAN}智能网络监控脚本 - Ubuntu系统级部署${NC}" +echo -e "${CYAN}==========================================${NC}" +echo "" + +echo -e "${YELLOW}部署计划:${NC}" +echo -e "- 程序目录: ${PROGRAM_PATH}" +echo -e "- 配置目录: ${CONFIG_PATH}" +echo -e "- 日志目录: ${LOG_PATH}" +echo -e "- 服务文件: ${SERVICE_FILE}" +echo "" + +# 检查root权限 +if [[ $EUID -ne 0 ]]; then + echo -e "${RED}错误:此脚本需要root权限执行${NC}" + echo -e "${YELLOW}请使用: sudo $0${NC}" + exit 1 +fi + +# 检查源文件 +REQUIRED_FILES=( + "smart_shutdown.sh" +) + +for file in "${REQUIRED_FILES[@]}"; do + if [[ ! -f "$SCRIPT_DIR/$file" ]]; then + echo -e "${RED}错误:找不到必需文件: $file${NC}" + exit 1 + fi +done + +echo -e "${GREEN}[OK] 源文件检查完成${NC}" + +# 停止已存在的服务 +if systemctl is-active --quiet "$SERVICE_NAME"; then + echo -e "${YELLOW}正在停止现有服务...${NC}" + systemctl stop "$SERVICE_NAME" + echo -e "${GREEN}[OK] 服务已停止${NC}" +fi + +# 创建目录结构 +echo -e "${YELLOW}正在创建目录结构...${NC}" + +# 创建程序目录 +if [[ ! -d "$PROGRAM_PATH" ]]; then + mkdir -p "$PROGRAM_PATH" + echo -e "${GREEN}[OK] 创建程序目录: $PROGRAM_PATH${NC}" +fi + +# 创建配置目录 +if [[ ! -d "$CONFIG_PATH" ]]; then + mkdir -p "$CONFIG_PATH" + echo -e "${GREEN}[OK] 创建配置目录: $CONFIG_PATH${NC}" +fi + +# 创建日志目录 +if [[ ! -d "$LOG_PATH" ]]; then + mkdir -p "$LOG_PATH" + # 设置适当的权限,允许服务用户写入 + chmod 755 "$LOG_PATH" + echo -e "${GREEN}[OK] 创建日志目录: $LOG_PATH${NC}" +fi + +# 创建系统优化版的主脚本 +echo -e "${YELLOW}正在创建系统版本的脚本...${NC}" + +cat > "$PROGRAM_PATH/smart_shutdown_system.sh" << 'EOF' +#!/bin/bash + +# +# 智能网络监控脚本 - 系统服务版本 +# +# 功能描述: +# 系统级网络监控脚本,在网络持续中断时自动关机 +# +# 特点: +# - 开机自启动,作为systemd服务运行 +# - 日志存储在系统日志目录 +# - 优化的错误处理和权限管理 +# + +# ==================== 系统级配置参数 ==================== + +# 默认配置参数 +TARGET_IP="192.168.3.3" +NORMAL_PING_INTERVAL=15 +MONITOR_WINDOW_SECONDS=180 +SHUTDOWN_COUNTDOWN=60 +COUNTDOWN_PING_INTERVAL=3 +PING_TIMEOUT=3 + +# 系统级路径配置 +CONFIG_FILE="/etc/smart-network-monitor/config.json" +LOG_DIRECTORY="/var/log/smart-network-monitor" +MAX_LOG_DAYS=30 + +# 正常连接时的日志记录间隔计数器 +NORMAL_LOG_INTERVAL=24 # 每24次循环记录一次状态 (约6分钟) +NORMAL_LOG_COUNTER=0 + +# ==================== 函数定义 ==================== + +# 日志写入函数 +write_log() { + local level="$1" + local message="$2" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local log_file="$LOG_DIRECTORY/network_monitor_$(date '+%Y%m%d').log" + local log_entry="[$timestamp] [$level] $message" + + # 确保日志目录存在 + mkdir -p "$LOG_DIRECTORY" + + # 写入日志文件 + echo "$log_entry" >> "$log_file" 2>/dev/null + + # 同时写入系统日志 + logger -t "smart-network-monitor" "$log_entry" + + # 对于关键信息,输出到标准输出(systemd会捕获) + if [[ "$level" == "CRITICAL" || "$level" == "SUCCESS" || "$level" == "WARN" ]]; then + echo "$log_entry" + fi +} + +# 加载配置文件 +load_configuration() { + if [[ -f "$CONFIG_FILE" ]]; then + write_log "INFO" "加载配置文件: $CONFIG_FILE" + + # 使用jq解析JSON配置文件(如果可用) + if command -v jq >/dev/null 2>&1; then + local target_ip=$(jq -r '.TargetIP // empty' "$CONFIG_FILE" 2>/dev/null) + local monitor_window=$(jq -r '.MonitorWindowSeconds // empty' "$CONFIG_FILE" 2>/dev/null) + local shutdown_countdown=$(jq -r '.ShutdownCountdown // empty' "$CONFIG_FILE" 2>/dev/null) + local ping_interval=$(jq -r '.NormalPingInterval // empty' "$CONFIG_FILE" 2>/dev/null) + + [[ -n "$target_ip" ]] && TARGET_IP="$target_ip" + [[ -n "$monitor_window" ]] && MONITOR_WINDOW_SECONDS="$monitor_window" + [[ -n "$shutdown_countdown" ]] && SHUTDOWN_COUNTDOWN="$shutdown_countdown" + [[ -n "$ping_interval" ]] && NORMAL_PING_INTERVAL="$ping_interval" + + write_log "SUCCESS" "配置文件加载成功" + else + write_log "WARN" "jq未安装,无法解析JSON配置文件,使用默认配置" + fi + else + write_log "WARN" "配置文件不存在,使用默认配置" + fi +} + +# 测试网络连接 +test_network_connection() { + local target_ip="$1" + ping -c 1 -W "$PING_TIMEOUT" "$target_ip" >/dev/null 2>&1 + return $? +} + +# 清理旧日志文件 +cleanup_old_logs() { + if [[ -d "$LOG_DIRECTORY" ]]; then + find "$LOG_DIRECTORY" -name "network_monitor_*.log" -type f -mtime +$MAX_LOG_DAYS -exec rm -f {} \; 2>/dev/null + fi +} + +# 信号处理函数 +cleanup_and_exit() { + write_log "INFO" "接收到退出信号,正在清理..." + write_log "INFO" "========== 服务退出 ==========" + exit 0 +} + +# ==================== 主程序开始 ==================== + +# 设置信号处理 +trap cleanup_and_exit SIGINT SIGTERM + +# 清理旧日志 +cleanup_old_logs + +# 加载配置 +load_configuration + +# 获取系统信息 +running_user=$(whoami) +local_ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' | head -1) +[[ -z "$local_ip" ]] && local_ip="未知" + +write_log "INFO" "========== 系统级网络监控服务启动 ==========" +write_log "INFO" "运行用户: $running_user" +write_log "INFO" "本机IP: $local_ip" +write_log "INFO" "监控目标: $TARGET_IP" +write_log "INFO" "监控窗口: ${MONITOR_WINDOW_SECONDS}秒" +write_log "INFO" "关机倒计时: ${SHUTDOWN_COUNTDOWN}秒" +write_log "INFO" "日志目录: $LOG_DIRECTORY" +write_log "INFO" "配置文件: $CONFIG_FILE" + +# 主循环 +failure_start_time="" + +while true; do + # 测试网络连接 + if test_network_connection "$TARGET_IP"; then + # 网络连接正常 + if [[ -n "$failure_start_time" ]]; then + write_log "SUCCESS" "网络连接已恢复" + failure_start_time="" + NORMAL_LOG_COUNTER=0 + else + # 减少正常连接时的日志频率 + ((NORMAL_LOG_COUNTER++)) + if [[ $NORMAL_LOG_COUNTER -ge $NORMAL_LOG_INTERVAL ]]; then + write_log "INFO" "网络连接正常(定期状态报告)" + NORMAL_LOG_COUNTER=0 + fi + fi + + sleep "$NORMAL_PING_INTERVAL" + + else + # 网络连接失败 + write_log "FAIL" "Ping失败 - 目标: $TARGET_IP" + + if [[ -z "$failure_start_time" ]]; then + failure_start_time=$(date +%s) + write_log "WARN" "网络首次中断,开始进入监控窗口计时" + fi + + current_time=$(date +%s) + failure_duration=$((current_time - failure_start_time)) + write_log "INFO" "网络已持续中断 $failure_duration / ${MONITOR_WINDOW_SECONDS} 秒" + + if [[ $failure_duration -ge $MONITOR_WINDOW_SECONDS ]]; then + write_log "CRITICAL" "网络持续中断已超过 ${MONITOR_WINDOW_SECONDS} 秒,开始关机流程" + + shutdown_cancelled=false + countdown_end_time=$((current_time + SHUTDOWN_COUNTDOWN)) + + while [[ $(date +%s) -lt $countdown_end_time && "$shutdown_cancelled" == "false" ]]; do + current_time=$(date +%s) + remaining_seconds=$((countdown_end_time - current_time)) + + if [[ $remaining_seconds -le 0 ]]; then + break + fi + + write_log "WARN" "距离关机还有 $remaining_seconds 秒... 正在快速检测网络" + + # 在倒计时中再次检测网络 + if test_network_connection "$TARGET_IP"; then + write_log "SUCCESS" "网络在倒计时期间恢复!取消关机" + failure_start_time="" + shutdown_cancelled=true + break + fi + + sleep "$COUNTDOWN_PING_INTERVAL" + done + + if [[ "$shutdown_cancelled" == "false" ]]; then + write_log "CRITICAL" "关机倒计时完成,执行系统关机命令" + + # 执行实际关机命令 + shutdown -h now + write_log "CRITICAL" "关机命令已执行" + + exit 0 + fi + else + sleep "$NORMAL_PING_INTERVAL" + fi + fi +done +EOF + +# 设置脚本权限 +chmod +x "$PROGRAM_PATH/smart_shutdown_system.sh" +echo -e "${GREEN}[OK] 创建系统脚本: $PROGRAM_PATH/smart_shutdown_system.sh${NC}" + +# 创建默认配置文件 +echo -e "${YELLOW}正在创建配置文件...${NC}" + +cat > "$CONFIG_PATH/config.json" << EOF +{ + "TargetIP": "192.168.3.3", + "MonitorWindowSeconds": 180, + "ShutdownCountdown": 60, + "NormalPingInterval": 15 +} +EOF + +echo -e "${GREEN}[OK] 创建配置文件: $CONFIG_PATH/config.json${NC}" + +# 创建systemd服务文件 +echo -e "${YELLOW}正在配置systemd服务...${NC}" + +cat > "$SERVICE_FILE" << EOF +[Unit] +Description=Smart Network Monitor Service +Documentation=https://github.com/example/smart-network-monitor +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=root +Group=root +ExecStart=$PROGRAM_PATH/smart_shutdown_system.sh +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal + +# 安全设置 +NoNewPrivileges=false +PrivateTmp=true +ProtectHome=true +ProtectSystem=strict +ReadWritePaths=$LOG_PATH + +# 环境变量 +Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +[Install] +WantedBy=multi-user.target +EOF + +echo -e "${GREEN}[OK] 创建systemd服务文件: $SERVICE_FILE${NC}" + +# 重新加载systemd配置 +echo -e "${YELLOW}正在重新加载systemd配置...${NC}" +systemctl daemon-reload +echo -e "${GREEN}[OK] systemd配置已重新加载${NC}" + +# 启用服务 +echo -e "${YELLOW}正在启用服务开机自启动...${NC}" +systemctl enable "$SERVICE_NAME" +echo -e "${GREEN}[OK] 服务已设置为开机自启动${NC}" + +# 创建管理脚本 +echo -e "${YELLOW}正在创建管理工具...${NC}" + +cat > "$PROGRAM_PATH/manage.sh" << 'EOF' +#!/bin/bash + +# +# 智能网络监控脚本 - 管理工具 +# + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +SERVICE_NAME="smart-network-monitor" +CONFIG_FILE="/etc/smart-network-monitor/config.json" +LOG_PATH="/var/log/smart-network-monitor" + +echo -e "${CYAN}智能网络监控脚本 - 管理工具${NC}" +echo -e "${CYAN}==============================${NC}" +echo "" + +echo -e "${YELLOW}可用操作:${NC}" +echo "1. 查看服务状态" +echo "2. 启动服务" +echo "3. 停止服务" +echo "4. 重启服务" +echo "5. 查看今天的日志" +echo "6. 查看实时日志" +echo "7. 查看配置文件" +echo "8. 编辑配置文件" +echo "9. 查看系统日志" +echo "" + +read -p "请选择操作 (1-9): " choice + +case "$choice" in + "1") + systemctl status "$SERVICE_NAME" + ;; + "2") + sudo systemctl start "$SERVICE_NAME" + echo -e "${GREEN}服务已启动${NC}" + ;; + "3") + sudo systemctl stop "$SERVICE_NAME" + echo -e "${GREEN}服务已停止${NC}" + ;; + "4") + sudo systemctl restart "$SERVICE_NAME" + echo -e "${GREEN}服务已重启${NC}" + ;; + "5") + log_file="$LOG_PATH/network_monitor_$(date '+%Y%m%d').log" + if [[ -f "$log_file" ]]; then + cat "$log_file" + else + echo -e "${RED}今天的日志文件不存在${NC}" + fi + ;; + "6") + log_file="$LOG_PATH/network_monitor_$(date '+%Y%m%d').log" + if [[ -f "$log_file" ]]; then + tail -f "$log_file" + else + echo -e "${RED}今天的日志文件不存在,显示systemd日志:${NC}" + journalctl -u "$SERVICE_NAME" -f + fi + ;; + "7") + if [[ -f "$CONFIG_FILE" ]]; then + cat "$CONFIG_FILE" + else + echo -e "${RED}配置文件不存在${NC}" + fi + ;; + "8") + if [[ -f "$CONFIG_FILE" ]]; then + sudo nano "$CONFIG_FILE" + echo -e "${YELLOW}配置已修改,重启服务使配置生效:${NC}" + echo "sudo systemctl restart $SERVICE_NAME" + else + echo -e "${RED}配置文件不存在${NC}" + fi + ;; + "9") + journalctl -u "$SERVICE_NAME" -n 50 + ;; + *) + echo -e "${RED}无效选择${NC}" + ;; +esac + +echo "" +echo -e "${YELLOW}常用命令:${NC}" +echo -e "${BLUE}查看服务状态:${NC} systemctl status $SERVICE_NAME" +echo -e "${BLUE}启动服务:${NC} sudo systemctl start $SERVICE_NAME" +echo -e "${BLUE}停止服务:${NC} sudo systemctl stop $SERVICE_NAME" +echo -e "${BLUE}重启服务:${NC} sudo systemctl restart $SERVICE_NAME" +echo -e "${BLUE}查看今天日志:${NC} cat $LOG_PATH/network_monitor_\$(date '+%Y%m%d').log" +echo -e "${BLUE}实时查看日志:${NC} tail -f $LOG_PATH/network_monitor_\$(date '+%Y%m%d').log" +echo -e "${BLUE}查看系统日志:${NC} journalctl -u $SERVICE_NAME -f" +echo -e "${BLUE}编辑配置:${NC} sudo nano $CONFIG_FILE" +echo "" +EOF + +chmod +x "$PROGRAM_PATH/manage.sh" +echo -e "${GREEN}[OK] 创建管理脚本: $PROGRAM_PATH/manage.sh${NC}" + +# 创建符号链接到系统PATH +if [[ ! -L "/usr/local/bin/smart-monitor" ]]; then + ln -s "$PROGRAM_PATH/manage.sh" "/usr/local/bin/smart-monitor" + echo -e "${GREEN}[OK] 创建管理工具快捷命令: smart-monitor${NC}" +fi + +echo "" +echo -e "${GREEN}[INFO] 系统级部署完成!${NC}" +echo "" +echo -e "${CYAN}部署摘要:${NC}" +echo -e "${GREEN}[OK]${NC} 程序文件已部署到: $PROGRAM_PATH" +echo -e "${GREEN}[OK]${NC} 配置目录已创建: $CONFIG_PATH" +echo -e "${GREEN}[OK]${NC} 日志目录已创建: $LOG_PATH" +echo -e "${GREEN}[OK]${NC} systemd服务已配置: $SERVICE_NAME" +echo -e "${GREEN}[OK]${NC} 开机自启动已启用" +echo "" +echo -e "${YELLOW}管理工具:${NC}" +echo -e "- 管理脚本: $PROGRAM_PATH/manage.sh" +echo -e "- 快捷命令: ${CYAN}smart-monitor${NC}" +echo -e "- 配置文件: $CONFIG_PATH/config.json" +echo -e "- 今天日志: $LOG_PATH/network_monitor_$(date '+%Y%m%d').log" +echo "" +echo -e "${GREEN}下次重启后,服务将自动运行!${NC}" +echo "" + +# 询问是否立即启动 +read -p "是否立即启动监控服务?(Y/n): " response +if [[ "$response" == "Y" || "$response" == "y" || "$response" == "" ]]; then + if systemctl start "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 监控服务已启动${NC}" + echo -e "${CYAN}使用以下命令查看服务状态:${NC}" + echo -e "${BLUE}systemctl status $SERVICE_NAME${NC}" + echo -e "${BLUE}journalctl -u $SERVICE_NAME -f${NC}" + else + echo -e "${RED}[X] 启动服务失败${NC}" + fi +fi + +echo "" +echo -e "${CYAN}使用 'smart-monitor' 命令来管理服务${NC}" \ No newline at end of file diff --git a/manage.sh b/manage.sh new file mode 100755 index 0000000..05b4b3d --- /dev/null +++ b/manage.sh @@ -0,0 +1,574 @@ +#!/bin/bash + +# +# 智能网络监控脚本 - 管理工具 +# +# 功能描述: +# 提供智能网络监控脚本的管理界面 +# 包括服务控制、日志查看、配置管理等功能 +# +# 使用方法: +# ./manage.sh +# 或者(如果已安装到系统):smart-monitor +# + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +PURPLE='\033[0;35m' +NC='\033[0m' # No Color + +# 系统路径配置 +SERVICE_NAME="smart-network-monitor" +SYSTEM_CONFIG_FILE="/etc/smart-network-monitor/config.json" +SYSTEM_LOG_PATH="/var/log/smart-network-monitor" +LOCAL_CONFIG_FILE="./config.json" +LOCAL_LOG_PATH="./logs" + +# 检测是否为系统级安装 +if [[ -f "$SYSTEM_CONFIG_FILE" ]]; then + CONFIG_FILE="$SYSTEM_CONFIG_FILE" + LOG_PATH="$SYSTEM_LOG_PATH" + IS_SYSTEM_INSTALL=true +else + CONFIG_FILE="$LOCAL_CONFIG_FILE" + LOG_PATH="$LOCAL_LOG_PATH" + IS_SYSTEM_INSTALL=false +fi + +# 显示标题 +show_header() { + clear + echo -e "${CYAN}==========================================${NC}" + echo -e "${CYAN}智能网络监控脚本 - 管理工具${NC}" + echo -e "${CYAN}==========================================${NC}" + echo "" + + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + echo -e "${GREEN}检测到系统级安装${NC}" + echo -e "服务名称: ${BLUE}$SERVICE_NAME${NC}" + else + echo -e "${YELLOW}使用本地模式${NC}" + echo -e "配置文件: ${BLUE}$CONFIG_FILE${NC}" + fi + echo -e "日志路径: ${BLUE}$LOG_PATH${NC}" + echo "" +} + +# 显示菜单 +show_menu() { + echo -e "${YELLOW}可用操作:${NC}" + + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + echo "1. 查看服务状态" + echo "2. 启动服务" + echo "3. 停止服务" + echo "4. 重启服务" + echo "5. 启用开机自启动" + echo "6. 禁用开机自启动" + echo "7. 查看今天的日志" + echo "8. 查看实时日志" + echo "9. 查看系统日志" + echo "10. 查看配置文件" + echo "11. 编辑配置文件" + echo "12. 测试网络连接" + echo "13. 显示服务信息" + echo "0. 退出" + else + echo "1. 查看配置文件" + echo "2. 编辑配置文件" + echo "3. 查看今天的日志" + echo "4. 查看实时日志" + echo "5. 测试网络连接" + echo "6. 启动本地脚本(前台运行)" + echo "7. 清理旧日志" + echo "0. 退出" + fi + echo "" +} + +# 检查服务状态 +check_service_status() { + if systemctl is-active --quiet "$SERVICE_NAME"; then + echo -e "${GREEN}✓ 服务正在运行${NC}" + return 0 + else + echo -e "${RED}✗ 服务未运行${NC}" + return 1 + fi +} + +# 显示服务状态 +show_service_status() { + echo -e "${CYAN}=== 服务状态 ===${NC}" + systemctl status "$SERVICE_NAME" --no-pager -l + echo "" + + echo -e "${CYAN}=== 服务是否启用 ===${NC}" + if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null; then + echo -e "${GREEN}✓ 开机自启动已启用${NC}" + else + echo -e "${YELLOW}✗ 开机自启动未启用${NC}" + fi + echo "" +} + +# 启动服务 +start_service() { + echo -e "${YELLOW}正在启动服务...${NC}" + if sudo systemctl start "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 服务已启动${NC}" + else + echo -e "${RED}[ERROR] 启动服务失败${NC}" + fi +} + +# 停止服务 +stop_service() { + echo -e "${YELLOW}正在停止服务...${NC}" + if sudo systemctl stop "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 服务已停止${NC}" + else + echo -e "${RED}[ERROR] 停止服务失败${NC}" + fi +} + +# 重启服务 +restart_service() { + echo -e "${YELLOW}正在重启服务...${NC}" + if sudo systemctl restart "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 服务已重启${NC}" + else + echo -e "${RED}[ERROR] 重启服务失败${NC}" + fi +} + +# 启用开机自启动 +enable_service() { + echo -e "${YELLOW}正在启用开机自启动...${NC}" + if sudo systemctl enable "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 开机自启动已启用${NC}" + else + echo -e "${RED}[ERROR] 启用开机自启动失败${NC}" + fi +} + +# 禁用开机自启动 +disable_service() { + echo -e "${YELLOW}正在禁用开机自启动...${NC}" + if sudo systemctl disable "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 开机自启动已禁用${NC}" + else + echo -e "${RED}[ERROR] 禁用开机自启动失败${NC}" + fi +} + +# 查看今天的日志 +show_today_log() { + local log_file="$LOG_PATH/network_monitor_$(date '+%Y%m%d').log" + + echo -e "${CYAN}=== 今天的日志 ($log_file) ===${NC}" + if [[ -f "$log_file" ]]; then + echo -e "${BLUE}文件大小: $(du -h "$log_file" | cut -f1)${NC}" + echo -e "${BLUE}最后修改: $(stat -c %y "$log_file")${NC}" + echo "" + echo -e "${YELLOW}最近20行:${NC}" + tail -n 20 "$log_file" + echo "" + echo -e "${CYAN}按任意键查看所有内容,或按 Ctrl+C 返回菜单${NC}" + read -n 1 -s + less "$log_file" + else + echo -e "${RED}今天的日志文件不存在${NC}" + echo -e "${BLUE}日志文件路径: $log_file${NC}" + fi +} + +# 查看实时日志 +show_live_log() { + local log_file="$LOG_PATH/network_monitor_$(date '+%Y%m%d').log" + + echo -e "${CYAN}=== 实时日志监控 ===${NC}" + echo -e "${YELLOW}按 Ctrl+C 退出实时监控${NC}" + echo "" + + if [[ -f "$log_file" ]]; then + tail -f "$log_file" + else + echo -e "${RED}今天的日志文件不存在,监控系统日志...${NC}" + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + journalctl -u "$SERVICE_NAME" -f + else + echo -e "${RED}无可用日志${NC}" + fi + fi +} + +# 查看系统日志 +show_system_log() { + echo -e "${CYAN}=== 系统日志 ===${NC}" + echo -e "${YELLOW}最近100条系统日志:${NC}" + journalctl -u "$SERVICE_NAME" -n 100 --no-pager + echo "" + echo -e "${CYAN}按任意键查看实时系统日志,或按 Ctrl+C 返回菜单${NC}" + read -n 1 -s + journalctl -u "$SERVICE_NAME" -f +} + +# 查看配置文件 +show_config() { + echo -e "${CYAN}=== 配置文件 ($CONFIG_FILE) ===${NC}" + if [[ -f "$CONFIG_FILE" ]]; then + echo -e "${BLUE}文件路径: $CONFIG_FILE${NC}" + echo -e "${BLUE}最后修改: $(stat -c %y "$CONFIG_FILE")${NC}" + echo "" + echo -e "${YELLOW}当前配置:${NC}" + cat "$CONFIG_FILE" + echo "" + + # 如果有jq,则格式化显示 + if command -v jq >/dev/null 2>&1; then + echo -e "${YELLOW}格式化显示:${NC}" + jq . "$CONFIG_FILE" 2>/dev/null || echo -e "${RED}JSON格式错误${NC}" + fi + else + echo -e "${RED}配置文件不存在: $CONFIG_FILE${NC}" + echo -e "${YELLOW}是否创建默认配置文件? (y/N): ${NC}" + read -n 1 response + echo "" + + if [[ "$response" == "y" || "$response" == "Y" ]]; then + create_default_config + fi + fi +} + +# 创建默认配置文件 +create_default_config() { + local config_dir=$(dirname "$CONFIG_FILE") + + # 确保配置目录存在 + if [[ ! -d "$config_dir" ]]; then + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + sudo mkdir -p "$config_dir" + else + mkdir -p "$config_dir" + fi + fi + + local default_config='{ + "TargetIP": "192.168.3.3", + "MonitorWindowSeconds": 180, + "ShutdownCountdown": 60, + "NormalPingInterval": 15 +}' + + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + echo "$default_config" | sudo tee "$CONFIG_FILE" > /dev/null + else + echo "$default_config" > "$CONFIG_FILE" + fi + + echo -e "${GREEN}[OK] 默认配置文件已创建: $CONFIG_FILE${NC}" +} + +# 编辑配置文件 +edit_config() { + if [[ ! -f "$CONFIG_FILE" ]]; then + echo -e "${YELLOW}配置文件不存在,是否创建默认配置? (y/N): ${NC}" + read -n 1 response + echo "" + + if [[ "$response" == "y" || "$response" == "Y" ]]; then + create_default_config + else + return + fi + fi + + echo -e "${CYAN}=== 编辑配置文件 ===${NC}" + echo -e "${YELLOW}使用编辑器编辑配置文件...${NC}" + + # 选择编辑器 + local editor="" + if command -v nano >/dev/null 2>&1; then + editor="nano" + elif command -v vi >/dev/null 2>&1; then + editor="vi" + else + echo -e "${RED}未找到可用的编辑器${NC}" + return + fi + + echo -e "${BLUE}使用编辑器: $editor${NC}" + echo -e "${YELLOW}编辑完成后,如果是系统安装,需要重启服务使配置生效${NC}" + echo "" + + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + sudo "$editor" "$CONFIG_FILE" + echo "" + echo -e "${YELLOW}配置已修改,是否重启服务使配置生效? (y/N): ${NC}" + read -n 1 response + echo "" + + if [[ "$response" == "y" || "$response" == "Y" ]]; then + restart_service + fi + else + "$editor" "$CONFIG_FILE" + fi +} + +# 测试网络连接 +test_network() { + local target_ip="192.168.3.3" + + # 尝试从配置文件读取目标IP + if [[ -f "$CONFIG_FILE" ]] && command -v jq >/dev/null 2>&1; then + local config_ip=$(jq -r '.TargetIP // empty' "$CONFIG_FILE" 2>/dev/null) + [[ -n "$config_ip" ]] && target_ip="$config_ip" + fi + + echo -e "${CYAN}=== 网络连接测试 ===${NC}" + echo -e "${BLUE}目标IP: $target_ip${NC}" + echo "" + + echo -e "${YELLOW}正在测试网络连接...${NC}" + + for i in {1..5}; do + echo -n "测试 $i/5: " + if ping -c 1 -W 3 "$target_ip" >/dev/null 2>&1; then + echo -e "${GREEN}✓ 连接成功${NC}" + else + echo -e "${RED}✗ 连接失败${NC}" + fi + [[ $i -lt 5 ]] && sleep 1 + done + + echo "" + echo -e "${CYAN}详细ping测试:${NC}" + ping -c 4 "$target_ip" +} + +# 启动本地脚本 +start_local_script() { + local script_path="./smart_shutdown.sh" + + echo -e "${CYAN}=== 启动本地脚本 ===${NC}" + + if [[ ! -f "$script_path" ]]; then + echo -e "${RED}本地脚本不存在: $script_path${NC}" + return + fi + + if [[ ! -x "$script_path" ]]; then + echo -e "${YELLOW}脚本没有执行权限,正在添加...${NC}" + chmod +x "$script_path" + fi + + echo -e "${YELLOW}即将启动本地脚本(前台运行)${NC}" + echo -e "${YELLOW}按 Ctrl+C 可以停止脚本${NC}" + echo -e "${BLUE}3秒后开始...${NC}" + + for i in {3..1}; do + echo -n "$i " + sleep 1 + done + echo "" + echo "" + + sudo "$script_path" +} + +# 清理旧日志 +cleanup_old_logs() { + echo -e "${CYAN}=== 清理旧日志 ===${NC}" + + if [[ ! -d "$LOG_PATH" ]]; then + echo -e "${RED}日志目录不存在: $LOG_PATH${NC}" + return + fi + + echo -e "${BLUE}日志目录: $LOG_PATH${NC}" + echo -e "${YELLOW}查找30天前的日志文件...${NC}" + + local old_logs=$(find "$LOG_PATH" -name "network_monitor_*.log" -type f -mtime +30 2>/dev/null) + + if [[ -z "$old_logs" ]]; then + echo -e "${GREEN}没有找到需要清理的旧日志文件${NC}" + return + fi + + echo -e "${YELLOW}找到以下旧日志文件:${NC}" + echo "$old_logs" + echo "" + + echo -e "${YELLOW}确定要删除这些文件吗? (y/N): ${NC}" + read -n 1 response + echo "" + + if [[ "$response" == "y" || "$response" == "Y" ]]; then + echo "$old_logs" | xargs rm -f + echo -e "${GREEN}[OK] 旧日志文件已清理${NC}" + else + echo -e "${YELLOW}清理已取消${NC}" + fi +} + +# 显示服务信息 +show_service_info() { + echo -e "${CYAN}=== 服务详细信息 ===${NC}" + + echo -e "${YELLOW}基本信息:${NC}" + echo -e "服务名称: ${BLUE}$SERVICE_NAME${NC}" + echo -e "配置文件: ${BLUE}$CONFIG_FILE${NC}" + echo -e "日志目录: ${BLUE}$LOG_PATH${NC}" + echo "" + + echo -e "${YELLOW}服务状态:${NC}" + systemctl show "$SERVICE_NAME" --no-pager + echo "" + + echo -e "${YELLOW}最近的服务日志:${NC}" + journalctl -u "$SERVICE_NAME" -n 10 --no-pager +} + +# 等待用户按键 +wait_for_key() { + echo "" + echo -e "${CYAN}按任意键继续...${NC}" + read -n 1 -s +} + +# 主程序 +main() { + while true; do + show_header + show_menu + + read -p "请选择操作: " choice + echo "" + + case "$choice" in + "1") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + show_service_status + else + show_config + fi + wait_for_key + ;; + "2") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + start_service + else + edit_config + fi + wait_for_key + ;; + "3") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + stop_service + else + show_today_log + fi + wait_for_key + ;; + "4") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + restart_service + else + show_live_log + fi + ;; + "5") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + enable_service + else + test_network + fi + wait_for_key + ;; + "6") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + disable_service + else + start_local_script + fi + wait_for_key + ;; + "7") + if [[ "$IS_SYSTEM_INSTALL" == "true" ]]; then + show_today_log + else + cleanup_old_logs + fi + ;; + "8") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && show_live_log + ;; + "9") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && show_system_log + ;; + "10") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && show_config + wait_for_key + ;; + "11") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && edit_config + wait_for_key + ;; + "12") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && test_network + wait_for_key + ;; + "13") + [[ "$IS_SYSTEM_INSTALL" == "true" ]] && show_service_info + wait_for_key + ;; + "0") + echo -e "${GREEN}再见!${NC}" + exit 0 + ;; + *) + echo -e "${RED}无效选择,请重新输入${NC}" + wait_for_key + ;; + esac + done +} + +# 检查依赖 +check_dependencies() { + local missing_deps=() + + # 检查必要命令 + for cmd in ping systemctl journalctl; do + if ! command -v "$cmd" >/dev/null 2>&1; then + missing_deps+=("$cmd") + fi + done + + if [[ ${#missing_deps[@]} -gt 0 ]]; then + echo -e "${RED}缺少必要的命令:${NC}" + for dep in "${missing_deps[@]}"; do + echo -e "${RED} - $dep${NC}" + done + echo -e "${YELLOW}请安装缺少的软件包${NC}" + exit 1 + fi + + # 检查可选命令 + if ! command -v jq >/dev/null 2>&1; then + echo -e "${YELLOW}建议安装 jq 以获得更好的JSON配置文件支持${NC}" + echo -e "${BLUE}安装命令: sudo apt-get install jq${NC}" + echo "" + fi +} + +# 启动主程序 +check_dependencies +main \ No newline at end of file diff --git a/smart_shutdown.ps1 b/smart_shutdown.ps1 index b0369c6..de6d58a 100644 --- a/smart_shutdown.ps1 +++ b/smart_shutdown.ps1 @@ -15,7 +15,7 @@ # ==================== 配置参数 ==================== # 监控的目标IP地址 -[string]$TargetIP = "192.168.3.3" +[string]$TargetIP = "192.168.3.15" # 正常监控时的ping间隔(秒) [int]$NormalPingInterval = 15 diff --git a/smart_shutdown.sh b/smart_shutdown.sh new file mode 100755 index 0000000..28b5a32 --- /dev/null +++ b/smart_shutdown.sh @@ -0,0 +1,316 @@ +#!/bin/bash + +# +# 智能网络监控脚本 - Ubuntu版本 +# +# 功能描述: +# 该脚本会定期测试与指定目标IP的网络连通性。 +# 如果在设定的"监控窗口"时间内连接持续失败,脚本将启动一个可取消的关机倒计时。 +# 如果在倒计时期间网络恢复,关机将被中止。 +# 所有操作都会被记录在日志文件中。 +# +# 使用方法: +# sudo ./smart_shutdown.sh +# +# 要求:需要root权限来执行关机命令 +# + +# ==================== 配置参数 ==================== + +# 监控的目标IP地址 +TARGET_IP="192.168.3.15" + +# 正常监控时的ping间隔(秒) +NORMAL_PING_INTERVAL=15 + +# 监控窗口时长(秒) - 在此期间持续失败则触发关机 +MONITOR_WINDOW_SECONDS=180 + +# 关机倒计时时长(秒) +SHUTDOWN_COUNTDOWN=60 + +# 关机倒计时阶段的ping间隔(秒) +COUNTDOWN_PING_INTERVAL=3 + +# ping超时时间(秒) +PING_TIMEOUT=3 + +# 日志配置 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LOG_DIRECTORY="$SCRIPT_DIR/logs" +MAX_LOG_DAYS=30 + +# 配置文件路径 +CONFIG_FILE="$SCRIPT_DIR/config.json" + +# ==================== 函数定义 ==================== + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +PURPLE='\033[0;35m' +NC='\033[0m' # No Color + +# 日志写入函数 +write_log() { + local level="$1" + local message="$2" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local log_file="$LOG_DIRECTORY/network_monitor_$(date '+%Y%m%d').log" + local log_entry="[$timestamp] [$level] $message" + + # 确保日志目录存在 + mkdir -p "$LOG_DIRECTORY" + + # 写入日志文件 + echo "$log_entry" >> "$log_file" + + # 根据日志级别在控制台输出不同颜色的信息 + case "$level" in + "SUCCESS") + echo -e "${GREEN}$log_entry${NC}" + ;; + "FAIL") + echo -e "${RED}$log_entry${NC}" + ;; + "WARN") + echo -e "${YELLOW}$log_entry${NC}" + ;; + "CRITICAL") + echo -e "${PURPLE}$log_entry${NC}" + ;; + "INFO") + echo -e "$log_entry" + ;; + *) + echo -e "$log_entry" + ;; + esac +} + +# 加载配置文件 +load_configuration() { + if [[ -f "$CONFIG_FILE" ]]; then + write_log "INFO" "加载配置文件: $CONFIG_FILE" + + # 使用jq解析JSON配置文件(如果可用) + if command -v jq >/dev/null 2>&1; then + local target_ip=$(jq -r '.TargetIP // empty' "$CONFIG_FILE" 2>/dev/null) + local monitor_window=$(jq -r '.MonitorWindowSeconds // empty' "$CONFIG_FILE" 2>/dev/null) + local shutdown_countdown=$(jq -r '.ShutdownCountdown // empty' "$CONFIG_FILE" 2>/dev/null) + local ping_interval=$(jq -r '.NormalPingInterval // empty' "$CONFIG_FILE" 2>/dev/null) + + [[ -n "$target_ip" ]] && TARGET_IP="$target_ip" + [[ -n "$monitor_window" ]] && MONITOR_WINDOW_SECONDS="$monitor_window" + [[ -n "$shutdown_countdown" ]] && SHUTDOWN_COUNTDOWN="$shutdown_countdown" + [[ -n "$ping_interval" ]] && NORMAL_PING_INTERVAL="$ping_interval" + + write_log "SUCCESS" "配置文件加载成功" + else + write_log "WARN" "jq未安装,无法解析JSON配置文件,使用默认配置" + fi + else + # 创建默认配置文件 + create_default_config + fi +} + +# 创建默认配置文件 +create_default_config() { + cat > "$CONFIG_FILE" << EOF +{ + "TargetIP": "$TARGET_IP", + "MonitorWindowSeconds": $MONITOR_WINDOW_SECONDS, + "ShutdownCountdown": $SHUTDOWN_COUNTDOWN, + "NormalPingInterval": $NORMAL_PING_INTERVAL +} +EOF + write_log "INFO" "创建默认配置文件: $CONFIG_FILE" +} + +# 获取本机IP地址 +get_local_ip() { + local local_ip + # 尝试获取默认路由接口的IP地址 + local_ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' | head -1) + + if [[ -z "$local_ip" ]]; then + # 备用方法:获取第一个非环回接口的IP + local_ip=$(ip addr show | grep -E 'inet [0-9]' | grep -v '127.0.0.1' | head -1 | awk '{print $2}' | cut -d'/' -f1) + fi + + [[ -n "$local_ip" ]] && echo "$local_ip" || echo "未知" +} + +# 测试网络连接 +test_network_connection() { + local target_ip="$1" + # 使用ping命令测试连接,发送1个包,超时时间为PING_TIMEOUT秒 + ping -c 1 -W "$PING_TIMEOUT" "$target_ip" >/dev/null 2>&1 + return $? +} + +# 清理旧日志文件 +cleanup_old_logs() { + if [[ -d "$LOG_DIRECTORY" ]]; then + # 删除超过MAX_LOG_DAYS天的日志文件 + find "$LOG_DIRECTORY" -name "network_monitor_*.log" -type f -mtime +$MAX_LOG_DAYS -exec rm -f {} \; 2>/dev/null + fi +} + +# 信号处理函数 +cleanup_and_exit() { + write_log "INFO" "接收到退出信号,正在清理..." + write_log "INFO" "========== 脚本退出 ==========" + exit 0 +} + +# 检查root权限 +check_root_permission() { + if [[ $EUID -ne 0 ]]; then + echo -e "${RED}错误:此脚本需要root权限才能执行关机操作${NC}" + echo -e "${YELLOW}请使用以下命令运行:${NC}" + echo -e "${CYAN}sudo $0${NC}" + exit 1 + fi +} + +# ==================== 主程序开始 ==================== + +# 设置信号处理 +trap cleanup_and_exit SIGINT SIGTERM + +# 检查权限 +check_root_permission + +# 清理旧日志 +cleanup_old_logs + +# 加载配置 +load_configuration + +# 初始化 +clear +local_ip=$(get_local_ip) +write_log "INFO" "========== 脚本启动 ==========" +write_log "INFO" "运行用户: $(whoami)" +write_log "INFO" "本机IP: $local_ip" +write_log "INFO" "监控目标: $TARGET_IP" +write_log "INFO" "监控窗口: ${MONITOR_WINDOW_SECONDS}秒" +write_log "INFO" "关机倒计时: ${SHUTDOWN_COUNTDOWN}秒" +write_log "INFO" "日志目录: $LOG_DIRECTORY" +write_log "INFO" "配置文件: $CONFIG_FILE" +write_log "INFO" "脚本已启动,按 Ctrl+C 退出..." + +echo "========================================" + +# 主循环变量 +failure_start_time="" +normal_status_counter=0 +normal_status_log_interval=24 # 每24次正常检测记录一次日志(约6分钟) + +# 主循环 +while true; do + # 测试网络连接 + if test_network_connection "$TARGET_IP"; then + # 网络连接正常 + if [[ -n "$failure_start_time" ]]; then + write_log "SUCCESS" "网络连接已恢复" + echo -e "${GREEN}[OK] 网络连接已恢复,重置监控窗口${NC}" + failure_start_time="" # 重置失败计时器 + normal_status_counter=0 # 重置正常状态计数器 + else + echo -e "${GREEN}[OK] 网络连接正常${NC}" + # 正常连接时减少日志频率,只定期记录 + ((normal_status_counter++)) + if [[ $normal_status_counter -ge $normal_status_log_interval ]]; then + write_log "INFO" "网络连接持续正常(已检测 $normal_status_counter 次)" + normal_status_counter=0 # 重置计数器 + fi + fi + + # 只在控制台显示等待信息,不写入日志文件 + echo -e "${CYAN}等待 ${NORMAL_PING_INTERVAL}秒后继续监控...${NC}" + sleep "$NORMAL_PING_INTERVAL" + + else + # 网络连接失败 + write_log "FAIL" "Ping失败 - 目标: $TARGET_IP" + + if [[ -z "$failure_start_time" ]]; then + # 记录首次失败的时间 + failure_start_time=$(date +%s) + write_log "WARN" "网络首次中断,开始进入监控窗口计时" + fi + + # 计算网络已中断的时间 + current_time=$(date +%s) + failure_duration=$((current_time - failure_start_time)) + write_log "INFO" "网络已持续中断 $failure_duration / ${MONITOR_WINDOW_SECONDS} 秒" + + # 显示详细状态 + remaining_time=$((MONITOR_WINDOW_SECONDS - failure_duration)) + echo -e "${YELLOW}监控状态 - 已中断: ${failure_duration}/${MONITOR_WINDOW_SECONDS}秒,剩余: ${remaining_time}秒${NC}" + + if [[ $failure_duration -ge $MONITOR_WINDOW_SECONDS ]]; then + # 持续失败时间超过监控窗口,开始关机倒计时 + write_log "CRITICAL" "网络持续中断已超过 ${MONITOR_WINDOW_SECONDS} 秒,开始关机流程" + echo "========================================" + + shutdown_cancelled=false + countdown_end_time=$((current_time + SHUTDOWN_COUNTDOWN)) + + while [[ $(date +%s) -lt $countdown_end_time && "$shutdown_cancelled" == "false" ]]; do + current_time=$(date +%s) + remaining_seconds=$((countdown_end_time - current_time)) + + if [[ $remaining_seconds -le 0 ]]; then + break + fi + + write_log "WARN" "距离关机还有 $remaining_seconds 秒... 正在快速检测网络" + echo "----------------------------------------" + echo -e "${YELLOW}距离关机还有 $remaining_seconds 秒...${NC}" + echo -e "${YELLOW}正在快速检测网络连接... 按 Ctrl+C 可取消关机${NC}" + + # 在倒计时中再次检测网络 + if test_network_connection "$TARGET_IP"; then + write_log "SUCCESS" "网络在倒计时期间恢复!取消关机" + echo "========================================" + echo -e "${GREEN}[OK] 网络连接已恢复!取消关机操作${NC}" + echo "========================================" + failure_start_time="" + shutdown_cancelled=true + break + else + echo -e "${RED}[X] 网络仍然中断${NC}" + fi + + # 等待下一次检测 + sleep "$COUNTDOWN_PING_INTERVAL" + done + + if [[ "$shutdown_cancelled" == "false" ]]; then + write_log "CRITICAL" "关机倒计时完成,执行系统关机命令" + + # 执行关机命令 + # 注意:为了安全起见,默认注释掉实际的关机命令 + # 如需启用,请取消下面一行的注释 + # shutdown -h now + + echo -e "${RED}模拟关机:shutdown -h now (为防止意外,此行已注释)${NC}" + write_log "CRITICAL" "关机命令已执行(模拟模式)" + + # 脚本执行完关机命令后可以退出 + exit 0 + fi + else + # 在监控窗口期内,继续等待 + write_log "INFO" "等待 ${NORMAL_PING_INTERVAL}秒后继续..." + sleep "$NORMAL_PING_INTERVAL" + fi + fi +done \ No newline at end of file diff --git a/uninstall_system.sh b/uninstall_system.sh new file mode 100755 index 0000000..2d2e35a --- /dev/null +++ b/uninstall_system.sh @@ -0,0 +1,223 @@ +#!/bin/bash + +# +# 智能网络监控脚本 - Ubuntu系统级卸载脚本 +# +# 功能描述: +# 完全卸载系统级部署的智能网络监控脚本 +# 包括停止服务、删除文件、清理配置等 +# +# 使用方法: +# sudo ./uninstall_system.sh +# + +# 设置颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +# 定义系统级路径 +PROGRAM_PATH="/opt/smart-network-monitor" +CONFIG_PATH="/etc/smart-network-monitor" +LOG_PATH="/var/log/smart-network-monitor" +SERVICE_FILE="/etc/systemd/system/smart-network-monitor.service" +SERVICE_NAME="smart-network-monitor" +SYMLINK_PATH="/usr/local/bin/smart-monitor" + +echo -e "${CYAN}==========================================${NC}" +echo -e "${CYAN}智能网络监控脚本 - Ubuntu系统级卸载${NC}" +echo -e "${CYAN}==========================================${NC}" +echo "" + +# 检查root权限 +if [[ $EUID -ne 0 ]]; then + echo -e "${RED}错误:此脚本需要root权限执行${NC}" + echo -e "${YELLOW}请使用: sudo $0${NC}" + exit 1 +fi + +echo -e "${YELLOW}将要删除的组件:${NC}" +echo -e "- 程序目录: ${PROGRAM_PATH}" +echo -e "- 配置目录: ${CONFIG_PATH}" +echo -e "- 日志目录: ${LOG_PATH}" +echo -e "- 服务文件: ${SERVICE_FILE}" +echo -e "- 符号链接: ${SYMLINK_PATH}" +echo "" + +# 询问用户确认 +read -p "确定要完全卸载智能网络监控脚本吗?这将删除所有相关文件和日志 (y/N): " confirm + +if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then + echo -e "${YELLOW}卸载已取消${NC}" + exit 0 +fi + +echo "" +echo -e "${YELLOW}开始卸载过程...${NC}" + +# 停止并禁用服务 +if systemctl is-active --quiet "$SERVICE_NAME"; then + echo -e "${YELLOW}正在停止服务...${NC}" + if systemctl stop "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 服务已停止${NC}" + else + echo -e "${RED}[WARNING] 停止服务失败${NC}" + fi +fi + +if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null; then + echo -e "${YELLOW}正在禁用服务自启动...${NC}" + if systemctl disable "$SERVICE_NAME"; then + echo -e "${GREEN}[OK] 服务自启动已禁用${NC}" + else + echo -e "${RED}[WARNING] 禁用服务自启动失败${NC}" + fi +fi + +# 删除服务文件 +if [[ -f "$SERVICE_FILE" ]]; then + echo -e "${YELLOW}正在删除服务文件...${NC}" + if rm -f "$SERVICE_FILE"; then + echo -e "${GREEN}[OK] 服务文件已删除: $SERVICE_FILE${NC}" + else + echo -e "${RED}[ERROR] 删除服务文件失败${NC}" + fi +fi + +# 重新加载systemd配置 +echo -e "${YELLOW}正在重新加载systemd配置...${NC}" +if systemctl daemon-reload; then + echo -e "${GREEN}[OK] systemd配置已重新加载${NC}" +else + echo -e "${RED}[WARNING] 重新加载systemd配置失败${NC}" +fi + +# 删除符号链接 +if [[ -L "$SYMLINK_PATH" ]]; then + echo -e "${YELLOW}正在删除符号链接...${NC}" + if rm -f "$SYMLINK_PATH"; then + echo -e "${GREEN}[OK] 符号链接已删除: $SYMLINK_PATH${NC}" + else + echo -e "${RED}[ERROR] 删除符号链接失败${NC}" + fi +fi + +# 删除程序目录 +if [[ -d "$PROGRAM_PATH" ]]; then + echo -e "${YELLOW}正在删除程序目录...${NC}" + if rm -rf "$PROGRAM_PATH"; then + echo -e "${GREEN}[OK] 程序目录已删除: $PROGRAM_PATH${NC}" + else + echo -e "${RED}[ERROR] 删除程序目录失败${NC}" + fi +fi + +# 询问是否删除配置文件 +echo "" +read -p "是否删除配置文件?这将删除您的自定义配置 (y/N): " delete_config + +if [[ "$delete_config" == "y" || "$delete_config" == "Y" ]]; then + if [[ -d "$CONFIG_PATH" ]]; then + echo -e "${YELLOW}正在删除配置目录...${NC}" + if rm -rf "$CONFIG_PATH"; then + echo -e "${GREEN}[OK] 配置目录已删除: $CONFIG_PATH${NC}" + else + echo -e "${RED}[ERROR] 删除配置目录失败${NC}" + fi + fi +else + echo -e "${BLUE}[INFO] 保留配置文件: $CONFIG_PATH${NC}" +fi + +# 询问是否删除日志文件 +echo "" +read -p "是否删除日志文件?这将删除所有监控历史记录 (y/N): " delete_logs + +if [[ "$delete_logs" == "y" || "$delete_logs" == "Y" ]]; then + if [[ -d "$LOG_PATH" ]]; then + echo -e "${YELLOW}正在删除日志目录...${NC}" + if rm -rf "$LOG_PATH"; then + echo -e "${GREEN}[OK] 日志目录已删除: $LOG_PATH${NC}" + else + echo -e "${RED}[ERROR] 删除日志目录失败${NC}" + fi + fi +else + echo -e "${BLUE}[INFO] 保留日志文件: $LOG_PATH${NC}" +fi + +# 清理系统日志中的相关条目(可选) +echo "" +read -p "是否清理系统日志中的相关条目?(y/N): " clean_syslogs + +if [[ "$clean_syslogs" == "y" || "$clean_syslogs" == "Y" ]]; then + echo -e "${YELLOW}正在清理系统日志...${NC}" + if command -v journalctl >/dev/null 2>&1; then + # 注意:journalctl --vacuum-time 需要适当的权限 + journalctl --vacuum-time=1d 2>/dev/null || echo -e "${YELLOW}[WARNING] 清理系统日志需要额外权限${NC}" + echo -e "${GREEN}[OK] 系统日志清理完成${NC}" + else + echo -e "${YELLOW}[WARNING] journalctl命令不可用${NC}" + fi +fi + +echo "" +echo -e "${GREEN}==========================================${NC}" +echo -e "${GREEN}卸载完成!${NC}" +echo -e "${GREEN}==========================================${NC}" +echo "" + +# 显示卸载摘要 +echo -e "${CYAN}卸载摘要:${NC}" +echo -e "${GREEN}[OK]${NC} 服务已停止并禁用" +echo -e "${GREEN}[OK]${NC} 服务文件已删除" +echo -e "${GREEN}[OK]${NC} 程序文件已删除" +echo -e "${GREEN}[OK]${NC} 符号链接已删除" + +if [[ "$delete_config" == "y" || "$delete_config" == "Y" ]]; then + echo -e "${GREEN}[OK]${NC} 配置文件已删除" +else + echo -e "${BLUE}[INFO]${NC} 配置文件已保留" +fi + +if [[ "$delete_logs" == "y" || "$delete_logs" == "Y" ]]; then + echo -e "${GREEN}[OK]${NC} 日志文件已删除" +else + echo -e "${BLUE}[INFO]${NC} 日志文件已保留" +fi + +echo "" + +# 检查是否有残留文件 +echo -e "${YELLOW}检查残留文件...${NC}" +remaining_files=() + +[[ -f "$SERVICE_FILE" ]] && remaining_files+=("$SERVICE_FILE") +[[ -d "$PROGRAM_PATH" ]] && remaining_files+=("$PROGRAM_PATH") +[[ -L "$SYMLINK_PATH" ]] && remaining_files+=("$SYMLINK_PATH") + +if [[ ${#remaining_files[@]} -eq 0 ]]; then + echo -e "${GREEN}[OK] 没有发现残留文件${NC}" +else + echo -e "${YELLOW}[WARNING] 发现以下残留文件:${NC}" + for file in "${remaining_files[@]}"; do + echo -e "${RED} - $file${NC}" + done + echo -e "${YELLOW}您可能需要手动删除这些文件${NC}" +fi + +echo "" +echo -e "${CYAN}智能网络监控脚本已完全卸载!${NC}" + +# 如果保留了配置或日志文件,提供再次卸载的说明 +if [[ "$delete_config" != "y" && "$delete_config" != "Y" ]] || [[ "$delete_logs" != "y" && "$delete_logs" != "Y" ]]; then + echo "" + echo -e "${BLUE}如果您之后想删除保留的文件,可以手动删除:${NC}" + [[ "$delete_config" != "y" && "$delete_config" != "Y" ]] && echo -e "${BLUE} 配置文件: sudo rm -rf $CONFIG_PATH${NC}" + [[ "$delete_logs" != "y" && "$delete_logs" != "Y" ]] && echo -e "${BLUE} 日志文件: sudo rm -rf $LOG_PATH${NC}" +fi + +echo "" \ No newline at end of file