首页 > 解决方案 > 在 docker 中执行脚本时,产生超过 545 个任务后等待报告的“pid X 不是此 shell 的子项”错误

问题描述

下面的脚本相当简单:它产生count任务然后等待它们。如果count大于 545,则在 docker 容器外部执行时运行良好,但在内部执行时失败。wait突然报告最老的任务PID未知。增加count1 将导致wait为另一个任务报告相同的错误,依此类推。请注意,所有生成的任务确实都已正确执行并退出。

test.sh

count=546
pids=()
for (( index=0; index < count; ++index ))
do
        sleep 2 &
        pid=${!}
        pids+=(${pid})
        #echo "spawned task #${index} PID ${pid}" 1>&2
done
echo "done spawning" 1>&2
sleep 5
for (( index=0; index < count; ++index ))
do
        pid=${pids[${index}]}
        wait ${pid}
        code=${?}
        if [[ 0 -eq ${code} ]]
        then
        :       #echo "reaped task #${index} PID ${pid}" 1>&2
        else
                echo "task #${index} PID ${pid} exited with code ${code}" 1>&2
                #exit ${code}
        fi
done
echo "done reaping" 1>&2
exit 0

Dockerfile

FROM ubuntu:18.04
COPY test.sh /
RUN bash /test.sh

docker build --no-cache "${PWD}"

完成
生成 test.sh:第 15 行:等待:pid 8 不是此 shell 任务的子
任务 #0 PID 8 退出,代码 127
完成收割

在线编译器

主机和容器都在使用 ubuntu:18.04、bash 4.4、docker 18.09.2 或 19.03.6(在不同的系统上尝试过)。

由于问题仅发生在生成的任务数量奇特的特定数量之后,我怀疑它必须达到某种隐含的限制。Bash 手册甚至将CHILD_MAX环境变量列为此类限制,但是通过运行脚本将其设置为较大的值CHILD_MAX=8190 bash ./test.sh不会改变任何内容。此外,添加jobs -l 2>&1before / aftersleep 5表明所有派生任务都已正确确认,它们列出了正确的 PID 和状态(尽管更多任务将被报告wait为不属于当前 shell)。我也尝试过检查一些可能相关的限制,但它们似乎都没有接近(getconf -a | grep CHILD_MAX产量 128275,cat "/proc/sys/kernel/pid_max" 1>&2产量 32768)。关于这里发生了什么以及如何解决这个问题的任何想法?

标签: bashdockerwaitbackground-task

解决方案


推荐阅读