需要 Bash 片段解释

需要 Bash 片段解释
i=0
while read M; do
    ((cd $DEST/cfg/puppet/modules/$M || exit 1
      [ -d .git ] && echo -n "$M: " && git pull) 2>&1 | prep $(printf %04d: $i) puppet/modules/$M) &
    i=$[i+1]
    [ $[ i % 20 ] = 0 ] && wait
done < $(dirname "$0")/modules-puppet.txt

有人可以解释一下[ $[ i % 20 ] = 0 ] && wait上面的 bash 片段中该行的作用吗?

答案1

该代码在循环中生成许多后台任务。这些任务中的每一个都运行与git和相关的命令puppet

这些作业可能生成得非常快,并且为了不压垮系统,代码在等待所有当前运行的后台任务完成之前仅运行其中 20 个作业。正是对 的调用wait使得脚本等待所有后台任务完成后再继续,从而产生另外 20 个作业。

调用之前的算术测试对于每个能被 20 整除wait的值都为真,即对于、等。$i$i = 20$i = 40

用于算术扩展的语法$[ ... ]是过时的bash语法,现在已经编写了$(( ... ))(可移植的)。该%运算符是普通的模运算符。


除了使用过时的语法之外,shell 还可能存在引用问题。变量扩展$DESTand$M和also$i缺少引号,两个命令替换也是如此。如果其中任何一个包含或生成存在于$IFS(默认情况下,空格、制表符、换行符)中的字符,您可能会认为脚本会失败或至少行为不当。

wait该代码在循环后还缺少final ,以正确等待循环启动的最后几个作业中的任何一个。如果可以保证循环将发生,则不需要这样做总是运行n*20时间(对于某个整数n)。

答案2

$[ i % 20 ]因算术扩展而被折旧,它被替换为$(()).

i % 20是算术运算“模”。

[ $[ i % 20 ] = 0 ]是一个条件语句,它不是标准的,另一种更具可读性的语法,Posix 可能是:

 if [ "$(( i % 20 ))" -eq 0 ]

&& wait仅当前一个命令的返回码等于 0 时才会执行。

[ $[ i % 20 ] = 0 ] && wait将测试模数,如果等于 0 那么wait

我的另一种完整语法可能是:

 if [ "$(( i % 20 ))" -eq 0 ] ; then
   wait
 fi

相关内容