Bash中如何统计后台进程数并逐个执行wait %i命令?
在Bash中逐个等待后台进程的方法
如果你需要统计脚本生成的后台进程数量,并且逐个执行wait %i(而不是一次性等待所有),可以通过两种可靠的方式实现:
方式一:启动后台进程时记录作业号
这种方法最可控,因为你在每个后台进程启动后立即捕获它的作业号,避免后续操作干扰作业列表。
# 初始化一个空数组,用来存储每个后台进程的作业号 bg_job_ids=() # 启动第一个后台进程 sleep 15 & # 提取刚启动的进程的作业号:通过jobs命令匹配PID,去掉%符号 latest_job=$(jobs -l | grep "$!" | awk '{print $1}' | tr -d '%') bg_job_ids+=("$latest_job") # 启动第二个后台进程 sleep 10 & latest_job=$(jobs -l | grep "$!" | awk '{print $1}' | tr -d '%') bg_job_ids+=("$latest_job") # 启动更多后台进程... # 遍历数组,逐个等待每个作业 for job_num in "${bg_job_ids[@]}"; do echo "开始等待作业 %${job_num}..." wait %"${job_num}" # 可选:获取该作业的退出状态 exit_status=$? echo "作业 %${job_num} 已完成,退出码:${exit_status}" done
关键说明:
$!会返回最后一个启动的后台进程的PID,我们用它来精准匹配对应的作业条目。jobs -l会列出当前shell(也就是你的脚本)所有后台作业的详细信息,包括作业号、PID和状态。tr -d '%'是为了把作业号里的%符号去掉,方便后续拼接成wait %X的格式。
方式二:直接提取当前所有后台作业号
如果你没有提前记录作业号,也可以在需要等待的时候,直接从jobs命令的输出中提取所有活跃(或已完成)的后台作业号:
# 获取当前脚本所有后台作业的作业号,去掉%符号 bg_job_ids=($(jobs | awk '{print $1}' | tr -d '%')) # 检查是否有后台作业需要等待 if [ ${#bg_job_ids[@]} -eq 0 ]; then echo "没有后台进程需要等待" exit 0 fi # 逐个等待每个作业 echo "共找到 ${#bg_job_ids[@]} 个后台作业,开始逐个等待..." for job_num in "${bg_job_ids[@]}"; do wait %"${job_num}" echo "作业 %${job_num} 完成" done
关键说明:
jobs命令默认只显示当前shell会话(即你的脚本)启动的后台作业,不会包含系统中其他无关进程,所以结果是准确的。- 即使有些后台进程已经完成,
wait %X仍然可以正常执行,并返回该进程的退出码,不会报错。
为什么不用通用的wait命令?
通用的wait(不带任何参数)会等待所有后台进程完成,但它无法让你逐个处理每个进程的完成事件——比如你想在每个进程结束后记录日志、处理输出,或者根据不同的退出码执行不同逻辑,这时候逐个wait %i就非常有用了。
内容的提问来源于stack exchange,提问作者AlwaysQuestioning
相关产品推荐
相关产品推荐

