如何以更规范简洁的方式监控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命令的退出码,精准覆盖三种场景:- 服务正常退出(状态码0):直接终止监控循环
- 输出超时(
read返回124):强制停止服务后重启 - 服务异常退出(非0状态码):短暂等待后自动重启
- 结构简洁易读:去掉了嵌套的
while true循环,逻辑线性化,新手也能快速理解 - 可维护性提升:把超时时间、配置文件路径做成变量,后续修改无需改动核心逻辑
- 安全规范:用双引号包裹变量,避免空格或特殊字符导致的命令解析错误
使用方式
和原有脚本一样,直接传入Docker Compose文件路径运行即可:
./monitor.sh your-compose.yml
内容的提问来源于stack exchange,提问作者pkq403
相关产品推荐
相关产品推荐

