为什么要减少shell变量作为未使用参数的副作用?

时间:2018-07-11 05:00:32

标签: bash

最近尝试调试一些网络代码时,我遇到了一个重试循环,以下面的简化形式显示:

while [ ${DELAY} -gt 0 ] ; do
    doSomething
    sleep 1
    : $((DELAY -= 1))
done

现在我知道它在做什么,我只是不确定为什么在那样做。 bash-builtins man页面状态:

  

: [arguments]无效;除了扩展参数和执行任何指定的重定向外,该命令没有任何作用。

由于您可以仅使用bash来修改((DELAY -= 1))中的变量,为什么这样做是作为将结果赋给{{1 }}命令,它可以评估但不使用它?

2 个答案:

答案 0 :(得分:1)

这实际上与自动错误处理有关。由于调用此代码的脚本正在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

并更改用于减少DELAY的行。

答案 1 :(得分:0)

如果set -x正在运行,将回显: 3: 2: 1的顺序。

这是减少和可选回显结果的“便宜”方法。