bash 等待所有进程完成(不起作用)

bash wait for all processes to finish (doesn't work)

我有一个目录,其中包含几个名称为

的子目录
1
2
3
4
backup_1
backup_2

我写了一个并行化的 bash 代码来处理这些文件夹中的文件,最小工作示例如下:

#!/bin/bash
P=`pwd`
task(){
    dirname=$(basename $dir)
    echo $dirname running >> output.out
    if [[ $dirname != "backup"* ]]; then
        sed -i "s/$dirname running/$dirname is good/" $P/output.out
    else
        sed -i "s/$dirname running/$dirname ignored/" $P/output.out
    fi
}

for dir in */; do
    ((i=i%8)); ((i++==0)) && wait
    task "$dir" &
done
wait
echo all done

脚本末尾的“等待”应该等待所有进程完成,然后再继续回显“全部完成”。 output.out 文件,所有进程完成后应该显示

1 is good
2 is good
3 is good
4 is good
backup_1 ignored
backup_2 ignored

如果我将脚本设置为 运行 与 ((i=i%1)); ((i++==0)) && wait 串行,我就能获得此输出。但是,如果我 运行 它与 ((i=i%2)); ((i++==0)) && wait 并行,我会得到类似

的东西
2 is good
1 running
3 running
4 is good
backup_1 running
backup_2 ignored

谁能告诉我为什么 wait 在这种情况下不起作用?

我也知道 GNU parallel 可以在并行化任务中做同样的事情。但是,我不知道如何在父目录中的所有子目录上并行命令 运行 此任务。如果有人可以生成我可以遵循的示例脚本,那就太好了。

非常感谢 亚采克

GNU Parallel 的文字移植看起来像这样:

task(){
    dir=""
    P=`pwd`
    dirname=$(basename $dir)
    echo $dirname running >> output.out
    if [[ $dirname != "backup"* ]]; then
        sed -i "s/$dirname running/$dirname is good/" $P/output.out
    else
        sed -i "s/$dirname running/$dirname ignored/" $P/output.out
    fi
}
export -f task

parallel -j8 task ::: */
echo all done

正如其他人指出的那样,当您 运行 sed 并行处理同一个文件时,您会遇到竞争条件。

要避免竞争条件,您可以这样做:

task(){
    dir=""
    P=`pwd`
    dirname=$(basename $dir)
    echo $dirname running
    if [[ $dirname != "backup"* ]]; then
        echo "$dirname is good" >&2
    else
        echo "$dirname ignored" >&2
    fi
}
export -f task

parallel -j8 task ::: */ >running.out 2>done.out
echo all done

您最终会得到两个文件 running.out 和 done.out。

如果你真的只想忽略名为 backup* 的目录:

task(){
    dir=""
    P=`pwd`
    dirname=$(basename $dir)
    echo $dirname running
    echo "$dirname is good" >&2
}
export -f task

parallel -j8 task '{=/backup/ and skip()=}' ::: */ >running.out 2>done.out
echo all done

考虑花 20 分钟阅读 https://doi.org/10.5281/zenodo.1146014 的第 1+2 章,您的命令行会因此而爱上您。