使用set -e导致Bash循环随机退出的问题排查求助
问题根源:
let 命令的退出状态码触发了 set -e 你遇到的问题核心在于**let命令的退出状态码规则**和set -e的行为冲突了:
set -e的作用是:当脚本中任何命令返回非零退出状态码时,立即终止脚本执行。- 而
let命令的退出状态码是由算术表达式的结果决定的:如果表达式求值为0,let返回1(非零);如果表达式结果非0,let返回0(成功)。
在你的循环里,像let "RRRR = $RANDOM % 256"这种语句,当$RANDOM % 256恰好等于0时,RRRR被赋值为0,此时let会返回状态码1,触发set -e的退出逻辑,导致脚本随机终止——因为$RANDOM是随机的,所以每次触发的时机都不一样。
解决方案
你有几种方式可以保留set -e同时避免这个问题:
1. 使用(( ))替代let(推荐)
Bash的算术扩展(( ))的退出状态码规则更符合直觉:只要算术运算本身没有语法错误,不管结果是0还是非0,都返回0(成功)。把所有let语句替换成(( ))即可,而且语法更简洁(不需要变量前加$):
(( MMMM = RANDOM % 254 + 2 )) (( NNNN = RANDOM % (MMMM - 1) + 1 )) (( RRRR = RANDOM % 256 )) (( XXXX = RANDOM % 256 )) (( DSXX = RANDOM % 128 + 1 )) (( OASM = RANDOM % 255 + 1 )) (( OLSM = RANDOM % 255 + 1 ))
2. 忽略let的退出状态码
如果一定要保留let,可以在每个let命令后面加上|| true,强制让这条命令的退出状态码变为0,即使let返回1也不会触发set -e:
let "MMMM = $RANDOM % 254 + 2" || true let "NNNN = $RANDOM % ($MMMM - 1) + 1" || true # 其他let语句同理
3. 局部禁用set -e
在循环内部临时关闭set -e,执行完算术运算后再重新启用:
set +e let "MMMM = $RANDOM % 254 + 2" let "NNNN = $RANDOM % ($MMMM - 1) + 1" # 其他let语句 set -e
内容的提问来源于stack exchange,提问作者Burt Wagner
相关产品推荐
相关产品推荐

