我无法解释以下程序的行为。我希望它进入一个无限循环,但它只是打印";你好&";。我能想到的唯一解释是,双括号之间的表达式的语义意味着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
遇到麻烦的常见方式之一——但我找不到。如果有人找到了,请将其标记为重复。]
((...))
算术条件构造对表达式求值,并根据求值结果设置其返回状态:
如果表达式的计算结果为零,则 非零 由于您有 参考:3.2.5.2条件结构((...))
将以((I++))
是post增量运算符:它计算为变量的当前值,该值为零。因此,退出状态为非零。set -e
,这将中止您的程序。