我有一个设置 -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 ))
你的算术。它也更有效率。