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
相关推荐
liweiweili12616 分钟前
Linux 中查询指定目录下查找包含特定文本的文件
linux·运维·chrome
YFLICKERH26 分钟前
【Linux系统】安装包 deb | rpm
linux·运维·安装包
Syron29 分钟前
ScaleSlider 组件实现
javascript
xhxxx32 分钟前
深入执行上下文:JavaScript 中 this 的底层绑定机制
javascript
DsirNg1 小时前
Vue 3:我在真实项目中如何用事件委托
前端·javascript·vue.js
克喵的水银蛇1 小时前
Flutter 适配实战:屏幕适配 + 暗黑模式 + 多语言
前端·javascript·flutter
冬男zdn1 小时前
Next.js 16 + next-intl App Router 国际化实现指南
javascript·typescript·reactjs
有意义1 小时前
this 不是你想的 this:从作用域迷失到调用栈掌控
javascript·面试·ecmascript 6
IT 乔峰1 小时前
linux部署DHCP服务端
linux·运维·网络
__beginner__2 小时前
docker安装influxdb
运维·docker·容器