首页 > 解决方案 > wait 不等待 while 循环中的进程完成

问题描述

这是我的代码:

count=0
head -n 10 urls.txt | while read LINE; do
        curl -o /dev/null -s "$LINE" -w "%{time_total}\n" &
    count=$((count+1))
    [ 0 -eq $((count % 3)) ] && wait && echo "process wait" # wait for 3 urls
done
echo "before wait"
wait
echo "after wait"

我希望在打印最后一个回声之前完成最后一个 curl,但实际上并非如此:

0.595499
0.602349
0.618237
process wait
0.084970
0.084243
0.099969
process wait
0.067999
0.068253
0.081602
process wait
before wait
after wait
➜  Downloads 0.088755 # already exited the script

有谁知道为什么会这样?以及如何解决这个问题?

标签: bash

解决方案


BashFAQ #24中所述,这是由于您的管道导致while循环在与脚本其余部分不同的 shell 中执行。

因此,您curl的 s 是该子外壳的子进程,而不是外部解释器;所以外部解释器不能wait为他们服务。

这可以通过不通过管道来解决while read,而是以一种不会将其混入管道元素的方式重定向其输入 - 与流程替换<(...)一样:

#!/usr/bin/env bash
#              ^^^^ - NOT /bin/sh; also, must not start with "sh scriptname"

count=0
while IFS= read -r line; do
    curl -o /dev/null -s "$line" -w "%{time_total}\n" &
    count=$((count+1))
    (( count % 3 == 0 )) && { wait; echo "process wait"; } # wait for 3 urls
done < <(head -n 10 urls.txt)
echo "before wait"
wait
echo "after wait"

推荐阅读