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
相关产品推荐
相关产品推荐

