Linux端口监控脚本

bash 复制代码
#!/bin/bash

# 端口监控脚本 
# 功能:监控多个端口,根据端口状态执行不同的启动脚本

# 监控间隔(秒)
CHECK_INTERVAL=300  # 5分钟

# 日志文件
LOG_FILE="./port_monitor.log"

# ========== 端口和脚本配置区域 ==========
# 在这里配置需要监控的端口和对应的启动脚本
# 格式: "端口号:启动脚本绝对路径"
PORT_SCRIPTS=(
    "8080:/home/user/scripts/start_web.sh"
    "3000:/home/user/scripts/start_api.sh" 
    "3306:/home/user/scripts/start_mysql.sh"
    "5432:/home/user/scripts/start_postgres.sh"
)
# ========== 配置结束 ==========

# 记录日志函数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 检查端口状态函数
check_port() {
    local port=$1
    
    # 方法1: 使用 netcat (如果可用)
    if command -v nc >/dev/null 2>&1; then
        if nc -z 127.0.0.1 "$port" >/dev/null 2>&1; then
            return 0  # 端口开放
        else
            return 1  # 端口关闭
        fi
    fi
    
    # 方法2: 使用 ss (如果可用)
    if command -v ss >/dev/null 2>&1; then
        if ss -tln | grep -q ":$port "; then
            return 0
        else
            return 1
        fi
    fi
    
    # 方法3: 使用 /proc/net/tcp
    local hex_port=$(printf '%04X' "$port")
    if grep -q ":$hex_port " /proc/net/tcp 2>/dev/null; then
        return 0
    else
        return 1
    fi
}

# 执行监控检查
monitor_ports() {
    log_message "=== 开始端口监控检查 ==="
    
    for port_script in "${PORT_SCRIPTS[@]}"; do
        # 解析端口和脚本
        IFS=':' read -r port script <<< "$port_script"
        
        log_message "检查端口: $port"
        
        if check_port "$port"; then
            log_message "✓ 端口 $port 状态正常"
        else
            log_message "✗ 端口 $port 异常 - 执行启动脚本: $script"
            
            # 检查脚本是否存在
            if [[ ! -f "$script" ]]; then
                log_message "错误: 脚本不存在: $script"
                continue
            fi
            
            # 检查脚本是否可执行
            if [[ ! -x "$script" ]]; then
                log_message "错误: 脚本不可执行: $script"
                continue
            fi
            
            # 执行启动脚本
            log_message "执行脚本: $script"
            if "$script" >> "$LOG_FILE" 2>&1; then
                log_message "脚本执行成功: $script"
            else
                log_message "脚本执行失败: $script (退出码: $?)"
            fi
        fi
    done
    
    log_message "=== 端口监控检查完成 ==="
}

# 显示当前配置
show_config() {
    log_message "当前监控配置:"
    for port_script in "${PORT_SCRIPTS[@]}"; do
        IFS=':' read -r port script <<< "$port_script"
        log_message "  端口 $port -> $script"
    done
}

# 主监控循环
start_monitor() {
    log_message "启动端口监控服务 (PID: $$)"
    log_message "监控间隔: ${CHECK_INTERVAL}秒"
    show_config
    
    # 保存PID到文件,便于管理
    echo $$ > /tmp/port_monitor.pid
    
    # 主循环
    while true; do
        monitor_ports
        log_message "等待 ${CHECK_INTERVAL} 秒后再次检查..."
        sleep "$CHECK_INTERVAL"
    done
}

# 停止监控
stop_monitor() {
    if [[ -f "/tmp/port_monitor.pid" ]]; then
        local pid=$(cat /tmp/port_monitor.pid)
        if kill -0 "$pid" 2>/dev/null; then
            kill "$pid"
            rm -f /tmp/port_monitor.pid
            log_message "端口监控服务已停止 (PID: $pid)"
        else
            rm -f /tmp/port_monitor.pid
            log_message "端口监控服务未运行"
        fi
    else
        log_message "端口监控服务未运行"
    fi
}

# 查看状态
check_status() {
    if [[ -f "/tmp/port_monitor.pid" ]]; then
        local pid=$(cat /tmp/port_monitor.pid)
        if kill -0 "$pid" 2>/dev/null; then
            log_message "端口监控服务运行中 (PID: $pid)"
            return 0
        else
            rm -f /tmp/port_monitor.pid
            log_message "端口监控服务未运行"
            return 1
        fi
    else
        log_message "端口监控服务未运行"
        return 1
    fi
}

# 单次检查
run_once() {
    log_message "执行单次端口检查"
    show_config
    monitor_ports
}

# 显示帮助
show_help() {
    cat << EOF
端口监控脚本 - 简化版

使用方法: $0 [命令]

命令:
    start     启动监控(后台运行)
    stop      停止监控
    status    查看监控状态
    once      执行一次监控检查
    help      显示帮助信息

配置说明:
    编辑脚本中的 PORT_SCRIPTS 数组来配置端口和脚本
    格式: "端口号:脚本路径"

示例:
    $0 start    # 启动监控
    $0 status   # 查看状态
    $0 stop     # 停止监控

日志文件: $LOG_FILE
EOF
}

# 脚本主入口
case "${1:-help}" in
    start)
        # 如果已经在运行,先停止
        if check_status >/dev/null 2>&1; then
            log_message "服务已在运行,先停止旧进程"
            stop_monitor
            sleep 2
        fi
        
        # 后台启动
        nohup "$0" daemon >> "$LOG_FILE" 2>&1 &
        log_message "端口监控服务已在后台启动 (PID: $!)"
        ;;
        
    daemon)
        # 守护进程模式
        start_monitor
        ;;
        
    stop)
        stop_monitor
        ;;
        
    status)
        check_status
        ;;
        
    once)
        run_once
        ;;
        
    help|--help|-h)
        show_help
        ;;
        
    *)
        echo "未知命令: $1"
        echo "使用: $0 help 查看帮助"
        exit 1
        ;;
esac

使用方法

1.修改脚本配置

编辑脚本中的 PORT_SCRIPTS 数组,设置你的端口和脚本

2.给监控脚本执行权限

bash 复制代码
chmod +x port_monitor.sh

3.启动监控

bash 复制代码
./port_monitor.sh start

4.查看状态

bash 复制代码
./port_monitor.sh status

5.停止监控

bash 复制代码
./port_monitor.sh stop

6.单次检查

bash 复制代码
./port_monitor.sh once

7.单次检查

bash 复制代码
tail -f ./port_monitor.log
相关推荐
用户12039112947261 小时前
深入JavaScript数组:从内存模型到遍历性能,打造高性能代码的基石
javascript
驯狼小羊羔1 小时前
学习随笔-http和https有何区别
前端·javascript·学习·http·https
KV_T1 小时前
centos运维常用命令
linux·运维·centos
进击的野人1 小时前
JavaScript DOM操作与事件处理:从小兔鲜儿电商网站看现代前端开发实践
前端·javascript
神秘的猪头1 小时前
JavaScript 数据结构入门:从数组开始掌握核心概念
前端·javascript
todoitbo1 小时前
使用n8n搭建服务器监控系统:从Webhook到Telegram告警的完整实现
运维·服务器·数据库·ai·向量数据库·流处理·n8n
dessler1 小时前
MYSQL-主键(Primary Key)
linux·运维·mysql
3秒一个大1 小时前
JavaScript Promise:异步编程的解析与实践
javascript
神秘的猪头2 小时前
CSS 定位详解与实战:掌握position的各种取值与css变量
前端·javascript
前端加油站2 小时前
透过现象看本质:CRUD系统的架构设计
前端·javascript