我正在编写一个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/