add linux support

This commit is contained in:
UnbalancedCat
2025-10-03 17:29:58 +08:00
parent 4b8e3da812
commit 82eeee50f1
6 changed files with 1932 additions and 1 deletions

290
README_Ubuntu.md Normal file
View File

@@ -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`
---
**享受智能网络监控带来的便利!** 🎉

528
deploy_system.sh Executable file
View File

@@ -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}"

574
manage.sh Executable file
View File

@@ -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

View File

@@ -15,7 +15,7 @@
# ==================== 配置参数 ==================== # ==================== 配置参数 ====================
# 监控的目标IP地址 # 监控的目标IP地址
[string]$TargetIP = "192.168.3.3" [string]$TargetIP = "192.168.3.15"
# 正常监控时的ping间隔 # 正常监控时的ping间隔
[int]$NormalPingInterval = 15 [int]$NormalPingInterval = 15

316
smart_shutdown.sh Executable file
View File

@@ -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

223
uninstall_system.sh Executable file
View File

@@ -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 ""