最近在尝试调试一些网络代码时,我遇到了一个重试循环,如下所示:
while [ ${DELAY} -gt 0 ] ; do
doSomething
sleep 1
: $((DELAY -= 1))
done
现在我明白了它在做什么,我只是不确定为什么会这样做。bash-builtins
man
页面状态:
: [arguments]
无效;该命令除了扩展参数和执行任何指定的重定向之外,什么都不做。
既然只需((DELAY -= 1))
就可以简单地修改bash
中的变量,那么它为什么要这样做作为将结果提供给:
命令的副作用呢?
这实际上与自动错误处理有关。因为调用此代码的脚本是在set -e
下运行的,所以一旦出现错误,它将立即退出。
您可以使用以下脚本看到效果:
set -e
DELAY=10
while [ ${DELAY} -gt 0 ] ; do
echo Delaying $DELAY
((DELAY -= 1))
done
echo Finishing
使用该脚本,您永远不会看到Finishing
行,因为"((DELAY -= 1))
的退出代码通常是0
,但当值降至零时是1
。这意味着运行中的set -e
将在该点停止脚本。
使用: $((DELAY -= 1))
将始终具有零退出代码,因此不会过早退出。
这种退出代码行为在以下情况下最为明显:
DELAY=10
while [ ${DELAY} -gt 0 ] ; do
echo Delaying $DELAY
# Select one of these below, comment the other:
((DELAY -= 1))
#: $((DELAY -= 1))
echo " Exit code $?"
done
echo Finishing
并且改变哪一行用于递减CCD_ 14。
如果set -x
正在运行,则会回显: 3
、: 2
、: 1
的序列。
这是一种"廉价"的方法,既可以递减,也可以选择性地回声结果。