当 let 或 expr 计算结果为 0 时 bash -e 退出

当 let 或 expr 计算结果为 0 时 bash -e 退出

我有一个设置 -e 的 bash 脚本,因此脚本将在任何退出状态 != 0 时退出。

我正在尝试执行一些分配给变量的基本 shell 算术,有时表达式等于 0,这会导致 let 或 expr 命令的退出状态为“1”。

这是一个例子:

#!/bin/bash -ex
echo "Test 1"
Z=`expr 1 - 1` || true
echo "Z will print"
let "A=4 - 4"
echo "A WILL NEVER PRINT $A"
Y=`expr 1 - 1`
echo "Y WILL NEVER PRINT $Y"
X=$(expr 2 - 2)
echo "X WILL NEVER PRINT $X"

输出是:

$ ./test_error.sh 
+ echo 'Test 1'
Test 1
++ expr 1 - 1
+ Z=0
+ true
+ echo 'Z will print'
Z will print
+ let 'A=4 - 4'

我的问题是,惯用的 bash 脚本编写方式是什么,允许脚本在真正的退出错误上失败,而不是在等于 0 的基本算术上失败。我可以在所有这些表达式后加上后缀:

A=`expr $C - $D`    || true

但这似乎很古怪。

答案1

不要用于expr算术。它早已过时:shell 现在内置了算术,带有构造$((…))(POSIX),或者带有let内置 (ksh/bash/zsh) 或((…))构造 (ksh/bash/zsh)。

let如果最后计算的表达式为 0,则((…))返回 1(失败状态代码)。为避免导致脚本在 下退出set -e,请安排最后一个表达式不返回 0,例如:

let "a = 2 - 2" 1
((a = 2 - 2, 1))

或者,使用以下|| true习语:

((a = 2 - 2)) || true

或者,在内部进行算术运算$((…)),在外部进行赋值。赋值返回值中最后一个命令替换的状态,如果没有命令替换,则返回 0,这样就安全了。这还有一个好处,就是可以在任何 POSIX shell(例如 dash)中工作。

a=$((2 - 2))

答案2

我有一样的问题。长话短说:

如果 [of let] 的最后一个 ARG 计算结果为 0,则 let 返回 1;否则,let 返回 0。

答案3

这个语法对我有用:

a=$((b + c))

答案4

代替$(( C - D ))你的算术。它也更有效率。

相关内容