问题描述
xiaoyakeeper 的 docker_pull() 在脚本已有长期后台任务时,可能在命令替换中的无参数 wait 处陷入高速错误循环:
/etc/xiaoya/aliyun_clear.sh: line 736: wait: pid 472 is not a child of this shell
该错误会被 Docker json-file 日志驱动持续写入磁盘。一次实际故障中,日志在约 68 分钟内增长到 17.1 GB,瞬时增长速度达到约 27 MB/s,险些写满系统盘。
环境
- 脚本版本:
202607301821
- 镜像:
ddsderek/xiaoyakeeper:latest
- 镜像 ID:
sha256:c68d27f0f2d7e56edbd5aa7a60daa463269779d41f47358c137459bf7c704c7e
- Bash:
5.3.3(1)-release (x86_64-alpine-linux-musl)
- Docker Server:
28.5.2
时间线
- 2026-07-30 23:05:28:检测到并开始更新至
202607301821
- 23:06:39:新版脚本开始运行
- 23:08:13:首次出现
wait: pid ... is not a child of this shell
- 2026-07-31 00:15:51:手动停止容器,此时日志为 17.1 GB
首次错误之前整个容器日志不足 1 MB,之后的空间增长几乎全部来自该错误循环。
最小复现
官方镜像中运行:
docker run --rm --entrypoint bash ddsderek/xiaoyakeeper:latest -c '
timeout 2 bash -c '\''
sleep 30 &
parent_bg=$!
result=$(sleep 0.01 & wait)
kill "$parent_bg" 2>/dev/null
'\'' 2>/tmp/wait.err
wc -c -l /tmp/wait.err
head -n 2 /tmp/wait.err
'
复现结果:2 秒内产生 388129 行、20766704 字节 stderr,进程无法自行结束:
bash: line 4: wait: pid 10 is not a child of this shell
原因分析
脚本会通过 start_push_proc 创建长期后台任务。docker_pull() 随后在命令替换子 shell 中启动多个后台 curl,并使用无参数 wait:
mirrors="$(
for line in $mirrors; do
curl ... &
done
wait
)"
Bash 5.3.3 的该子 shell 会看到父 shell 的后台作业记录,但对应 PID 并不是它的子进程。无参数 wait 因而反复尝试等待该 PID并持续报错。
建议修复
只记录这一批测速 curl 的 PID,并逐个显式等待:
pids=""
for line in $mirrors; do
curl ... &
pids="$pids $!"
done
for pid in $pids; do
wait "$pid"
done
相同环境的验证结果:显式 PID 版本正常退出,stderr 为 0;同时保留并发测速行为。
另外建议为容器配置日志轮转作为第二层保护,但这不能替代脚本死循环修复。
问题描述
xiaoyakeeper的docker_pull()在脚本已有长期后台任务时,可能在命令替换中的无参数wait处陷入高速错误循环:该错误会被 Docker
json-file日志驱动持续写入磁盘。一次实际故障中,日志在约 68 分钟内增长到 17.1 GB,瞬时增长速度达到约 27 MB/s,险些写满系统盘。环境
202607301821ddsderek/xiaoyakeeper:latestsha256:c68d27f0f2d7e56edbd5aa7a60daa463269779d41f47358c137459bf7c704c7e5.3.3(1)-release (x86_64-alpine-linux-musl)28.5.2时间线
202607301821wait: pid ... is not a child of this shell首次错误之前整个容器日志不足 1 MB,之后的空间增长几乎全部来自该错误循环。
最小复现
官方镜像中运行:
复现结果:2 秒内产生 388129 行、20766704 字节 stderr,进程无法自行结束:
原因分析
脚本会通过
start_push_proc创建长期后台任务。docker_pull()随后在命令替换子 shell 中启动多个后台curl,并使用无参数wait:Bash 5.3.3 的该子 shell 会看到父 shell 的后台作业记录,但对应 PID 并不是它的子进程。无参数
wait因而反复尝试等待该 PID并持续报错。建议修复
只记录这一批测速
curl的 PID,并逐个显式等待:相同环境的验证结果:显式 PID 版本正常退出,stderr 为 0;同时保留并发测速行为。
另外建议为容器配置日志轮转作为第二层保护,但这不能替代脚本死循环修复。