我正在编写一个bash脚本,该脚本启动一些模拟,然后根据这些模拟生成的输出绘制一组图。
我想并行运行模拟,但需要脚本“阻塞”等待所有模拟完成,然后再转到绘图生成脚本。

pids=()

for file in inputdir/*
do
    ./run_simulation $file &> /dev/null & pids+=($!)
done

# synchronization barrier
for pid in ${pids[*]}; do
    wait $pid
done

当前的脚本工作得很好,我只是很好奇:与${pids[@]}相比,使用${pids[*]}有什么区别?(我的剧本用的是前者)。

最佳答案

实际上,如果您确定IFS只包含一个合理的正常值,这并不重要。(如果它包含可以在PID内部存在的数字字符,那么您的值可能会被额外的操作“cc>”所破坏。
然而,${pids[*]}是正确的,因为它的语义是您想要的:将数组中的每个项扩展为一个单词。
运行"${pids[@]}"时,shell将列表扩展为单个字符串,用${pids[*]}中的第一个字符(默认情况下为空格)分隔后续元素。然后,它将结果作为字符串拆分的主题(将其从单个字符串拆分回单独项的列表),并将该拆分操作的每个结果展开为glob。
下面是一个具体的例子:

pids=( 123 456 789 012 )
IFS=02468 # now entering Insanity World!
echo "${pids[@]}"  # still works correctly
echo ${pids[*]}    # not so much

…将作为其两行输出(如https://ideone.com/mqtEfQ所示):
123 456 789 012
1 3  5  7 9  1

…因为IFS中的数字用于拆分成单独的IFS参数,而不是作为文本数据传递。

关于bash - 等待多个bash进程完成时,应该使用$ {pids [*]}还是$ {pids [@]}?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54680855/

10-09 22:26