You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以更规范简洁的方式监控Docker Compose服务的stdout无活动状态并按需重启,同时尊重正常退出码?

优化后的简洁规范脚本方案

我帮你重构了脚本,让逻辑更清晰、符合Bash最佳实践,同时完美满足你的核心需求:仅在无输出超时或异常退出时重启服务,正常退出则停止监控循环。

#!/bin/bash
set -eo pipefail  # 确保管道中任意命令失败都能被正确捕获

# 配置参数,方便后续修改
COMPOSE_FILE="$1"
INACTIVITY_TIMEOUT=600  # 10分钟,单位:秒

while true; do
    echo "=== Starting service using compose file: $COMPOSE_FILE ==="
    # 运行Docker Compose并实时监控其输出
    docker compose -f "$COMPOSE_FILE" up | while IFS= read -r -t "$INACTIVITY_TIMEOUT" line; do
        # 实时转发服务输出到控制台
        echo "$line"
    done

    # 获取管道中各命令的退出状态码
    COMPOSE_EXIT_CODE=${PIPESTATUS[0]}
    READ_EXIT_CODE=${PIPESTATUS[1]}

    # 根据不同状态分支处理
    if [ "$COMPOSE_EXIT_CODE" -eq 0 ]; then
        echo "✅ Service exited normally (exit code 0), stopping monitoring loop."
        break
    elif [ "$READ_EXIT_CODE" -eq 124 ]; then
        echo "⚠️ No stdout output for $INACTIVITY_TIMEOUT seconds! Restarting service..."
        docker compose -f "$COMPOSE_FILE" down
    else
        echo "❌ Service exited with error code $COMPOSE_EXIT_CODE, restarting in 1 second..."
        sleep 1
    fi
done

关键优化点说明

  • 错误捕获更可靠:set -eo pipefail让管道中任何一步出错都会暴露真实的退出状态,避免隐藏潜在问题。
  • 精准状态区分:用PIPESTATUS数组分别获取docker compose up和read命令的退出码,精准覆盖三种场景:
    1. 服务正常退出(状态码0):直接终止监控循环
    2. 输出超时(read返回124):强制停止服务后重启
    3. 服务异常退出(非0状态码):短暂等待后自动重启
  • 结构简洁易读:去掉了嵌套的while true循环,逻辑线性化,新手也能快速理解
  • 可维护性提升:把超时时间、配置文件路径做成变量,后续修改无需改动核心逻辑
  • 安全规范:用双引号包裹变量,避免空格或特殊字符导致的命令解析错误

使用方式

和原有脚本一样,直接传入Docker Compose文件路径运行即可:

./monitor.sh your-compose.yml

内容的提问来源于stack exchange,提问作者pkq403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 06:34:17