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

如何让Makefile等待脚本中的后台进程执行完成?

问题背景

现有如下Makefile内容:

MAKEFLAGS += -s
SHELL := /bin/bash

all:
    $(MAKE) step1
    $(MAKE) -j 2 step2 step3
    $(MAKE) step4

step1:
    $(MAKE) step1_execute

step1_execute:
    echo "Running step 1..."
    ./createFileWithTime.sh output/step1_output
    echo "step1 completed."

step2:
    $(MAKE) step2_execute

step2_execute:
    echo "Running step 2..."
    ./createFileWithTime.sh output/step2_output
    echo "step2 completed."

step3:
    $(MAKE) step3_execute

step3_execute:
    echo "Running step 3..."
    ./createFileWithTime.sh output/step3_output
    echo "step3 completed."

step4:
    $(MAKE) step4_execute

step4_execute:
    echo "Running step 4..."
    ./createFileWithTime.sh output/step4_output
    echo "step4 completed."

配套的createFileWithTime.sh脚本内容如下:

#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

file_path="$1"
dir_name=$(dirname "$file_path")

if [ ! -d "$dir_name" ]; then
    mkdir -p "$dir_name"
fi

current_date=$(date +"%Y-%m-%d %H:%M:%S.%N")

echo "$current_date" > "$file_path"

sleep 3 &

echo "File '$file_path' created with current date and time: $current_date"

问题在于脚本里用后台方式执行sleep 3,导致Makefile不等脚本的所有进程跑完就继续执行后续步骤。比如跑make all时,输出文件的生成没有预期的3秒延迟。

要求:不能修改脚本本身,必须保留<step_name>和<step_name>_execute的组合目标结构,也不能指定依赖,怎么让Makefile等脚本里的所有命令(包括后台启动的进程)执行完再继续?

解决方案

核心是让Makefile在执行脚本后,等待脚本启动的所有后台子进程完成。可以把脚本执行和wait命令放在同一个子shell里,这样wait会等子shell内的所有后台进程结束,Makefile才会继续往下走。

修改后的Makefile如下:

MAKEFLAGS += -s
SHELL := /bin/bash

all:
    $(MAKE) step1
    $(MAKE) -j 2 step2 step3
    $(MAKE) step4

step1:
    $(MAKE) step1_execute

step1_execute:
    echo "Running step 1..."
    (./createFileWithTime.sh output/step1_output; wait)
    echo "step1 completed."

step2:
    $(MAKE) step2_execute

step2_execute:
    echo "Running step 2..."
    (./createFileWithTime.sh output/step2_output; wait)
    echo "step2 completed."

step3:
    $(MAKE) step3_execute

step3_execute:
    echo "Running step 3..."
    (./createFileWithTime.sh output/step3_output; wait)
    echo "step3 completed."

step4:
    $(MAKE) step4_execute

step4_execute:
    echo "Running step 4..."
    (./createFileWithTime.sh output/step4_output; wait)
    echo "step4 completed."

原理说明

  • 括号()会启动一个新的bash子shell,脚本在这个子shell里运行,它启动的后台sleep进程属于这个子shell的子进程。
  • 子shell里的wait命令会默认等待所有后台子进程执行完毕,之后子shell才会退出。
  • 这样Makefile会等整个子shell执行完成(包括后台sleep的3秒),再执行后续的提示语句和其他步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:16:10