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

bash脚本两两批量执行未等待子进程完成问题排查

问题排查:主脚本未等待子脚本执行完成就继续运行

问题描述

我有一个存放临时生成bash脚本的文件夹,编写了一段脚本遍历该文件夹,每次执行两个脚本,但该脚本完全未等待执行完成就继续运行。以下是主执行脚本和子脚本代码:

主脚本

#!/bin/bash

set -x

echo "Starting temp runner"

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

temp_scripts_folder="$script_dir/temp"

mapfile -t scripts < <(find "$temp_scripts_folder" -maxdepth 1 -type f -name "*.sh")

for ((i = 0; i < ${#scripts[@]}; i+=2)); do
    script1="${scripts[i]}"
    script2="${scripts[i+1]}"

    if [[ -n $script2 ]]; then
        echo "Script 1: $script1 and Script 2: $script2"

        echo "execution $script1"
        echo "logs are $script1.logs"
        sudo chmod +x "$script1" && "$script1" >> "$script1.logs" 2>&1 &
        pid1=$!

        echo "execution $script2"
        echo "logs are $script2.logs"
        sudo chmod +x "$script2" && "$script2" >> "$script2.logs" 2>&1 &
        pid2=$!

        # Wait for both scripts to finish
        wait $pid1 $pid2

    else
        if [ -f "$script1" ]; then
            echo "Only one file is found: $script1"
            echo "execution $script1"
            sudo chmod +x "$script1" && "$script1" >> "$script1.logs" 2>&1 &
            pid1=$!
            # Wait for the script to finish
            wait $pid1
        else
            echo "File does not exist: $script1"
        fi
    fi
done
wait 

echo "All scripts executed."

子脚本

#!/bin/bash
set -x
cd /home/ubuntu/azure/API
sudo docker compose up -d --build >> /home/ubuntu/deployment/logs/API.logs 2>&1 &

问题根源

问题出在子脚本的最后一行:你给docker compose up -d --build命令加了末尾的&,这会让docker compose命令直接在后台运行,子脚本本身会立刻执行完毕并退出。

主脚本里的wait $pid1 $pid2等待的是子脚本的进程ID,但子脚本已经提前退出了,所以主脚本会误以为任务已经完成,直接进入下一轮循环,而实际的docker compose构建和容器启动进程还在后台运行。

解决方案

去掉子脚本中docker compose命令末尾的&,修改后的子脚本如下:

#!/bin/bash
set -x
cd /home/ubuntu/azure/API
sudo docker compose up -d --build >> /home/ubuntu/deployment/logs/API.logs 2>&1

这样修改后,子脚本会等待docker compose up -d --build命令完全执行完成(包括镜像构建、容器启动的所有步骤)后才会退出,主脚本的wait命令才能正确等到子脚本执行完毕,再继续下一组脚本的执行。

如果确实需要让容器在后台运行,-d参数已经足够实现这个需求,它会在镜像构建完成后将容器后台启动,命令本身会在构建完成后结束,无需额外添加&。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:02:28