双括号中的表达式是否意味着bash函数中的返回



我无法解释以下程序的行为。我希望它进入一个无限循环,但它只是打印";你好&";。我能想到的唯一解释是,双括号之间的表达式的语义意味着bash函数中的return,但我找不到任何关于这方面的文档,所以我可能错了。

#!/usr/bin/env bash
set -euo pipefail
foo(){
I=0
while : ; do
echo "Hello!"
((I++))
sleep 1
echo "You won't reach here"
done
}
foo

这是errexit模式(也称为set -e(的不明显影响之一。有关此模式问题的更多信息,请参阅BashFAQ 105:为什么set-e(或set-o errexit,或trap ERR(没有达到我的预期?

在这种特殊情况下,问题是(( ))评估算术表达式,并且具有取决于该表达式是否为"0"的退出状态;真";(即非零(或"0";false";(零(。当表达式实际上是一个真/假表达式(如(( 1 == 2 ))(时,这是有意义的,但对于((I++)),表达式会递增I,然后返回其的原始值。由于表达式的求值结果为零,因此(( ))具有错误/失败退出状态,该状态被视为错误,并导致脚本退出。

[BTW,我本可以发誓,我们对这种确切的情况还有其他问题——这是set -e遇到麻烦的常见方式之一——但我找不到。如果有人找到了,请将其标记为重复。]

((...))算术条件构造对表达式求值,并根据求值结果设置其返回状态:

如果表达式的计算结果为,则((...))将以

非零((I++))post增量运算符:它计算为变量的当前值,该值为零。因此,退出状态为非零。

由于您有set -e,这将中止您的程序。

参考:3.2.5.2条件结构

最新更新