Shell脚本中依赖启动顺序的轮询检测需先启动前置服务,再用循环+条件判断+休眠检测其就绪:①用nc或/dev/tcp检测TCP端口;②用curl检测HTTP健康接口;③用test检测文件/目录存在;均须设超时并exit 1失败。
在 shell 脚本中实现“依赖启动顺序”的轮询检测,核心是:先启动前置服务(如数据库、redis),再等待其就绪(端口可连、接口返回成功等),最后启动当前服务。轮询检测就是用循环 + 条件判断 + 休眠,反复检查依赖是否可用。
检测 TCP 端口是否监听(最常用)
适用于 MySQL、PostgreSQL、Redis、Nginx 等监听端口的服务。用 nc(netcat)或 timeout + bash 内置 /dev/tcp 方式验证连接可达性。
示例脚本片段:
wait_for_port() {
local host="$1"
local port="$2"
local timeout=${3:-60} # 默认 60 秒超时
local elapsed=0
<p>while ! nc -z "$host" "$port" 2>/dev/null; do
if [ $elapsed -ge $timeout ]; then
echo "ERROR: Timeout waiting for $host:$port"
exit 1
fi
echo "Waiting for $host:$port... ($elapsed/$timeout)"
sleep 2
((elapsed += 2))
done
echo "$host:$port is ready."
}</p><h1>使用示例:等待本地 MySQL(3306)</h1><p>wait_for_port "127.0.0.1" "3306" 120
</p>检测 HTTP 接口返回健康状态
适合依赖 Spring Boot Actuator、Nginx status、自定义 /health 端点的服务。用 curl 检查响应码和内容。
关键点:忽略 SSL 错误、设置超时、检查 HTTP 状态码、可选校验响应体。
wait_for_http() {
local url="$1"
local expected_status=${2:-200}
local timeout=${3:-60}
local elapsed=0
<p>while true; do
http_code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$url" 2>/dev/null)
if [ "$http_code" = "$expected_status" ]; then
echo "$url is healthy (HTTP $http_code)."
return 0
fi</p><pre class="brush:php;toolbar:false;">if [ $elapsed -ge $timeout ]; then
echo "ERROR: Timeout waiting for HTTP $expected_status at $url"
exit 1
fi
echo "Waiting for $url ... got $http_code ($elapsed/$timeout)"
sleep 3
((elapsed += 3))done }
使用示例:等待后端服务健康检查
wait_for_http "https://www.php.cn/link/840b2c22efca496f247caa4063cadd8c" "200" 90
检测文件或目录存在(轻量级依赖)
适用于依赖某个初始化完成标记(如 Docker 中 init 容器写入的 /ready 文件)、配置生成完毕等场景。
wait_for_file() {
local path="$1"
local timeout=${2:-30}
local elapsed=0
<p>while [ ! -f "$path" ] && [ ! -d "$path" ]; do
if [ $elapsed -ge $timeout ]; then
echo "ERROR: Timeout waiting for file/directory: $path"
exit 1
fi
echo "Waiting for $path... ($elapsed/$timeout)"
sleep 1
((elapsed++))
done
echo "$path is available."
}</p><h1>使用示例:等待配置挂载完成</h1><p>wait_for_file "/etc/myapp/config.yaml"
</p>组合多个依赖 + 设置重试策略
真实场景常需串行等待多个服务。建议封装为函数,失败立即退出,并加入简单退避(如 sleep 逐渐加长)提升健壮性。
小技巧:
- 所有 wait 函数统一返回非 0 表示失败,主流程用
set -e自动中断 - 避免无限循环:必须设超时,且超时后
exit 1 - 日志输出带时间戳或序号,便于排查启动卡点
- Docker 中推荐用
docker-compose --wait(v2.23+)替代手写,但底层逻辑一致











