7.1 测试结构
if/then结构是用来检测一系列命令的 退出状态 是否为0(按 UNIX 惯例,退出码 0 表示命令执行成功),如果为0,则执行接下来的一个或多个命令。
(( 0 && 1 )) # 逻辑与
echo $? # 1 ***
# 然后 ...
let "num = (( 0 && 1 ))"
echo $num # 0
# 然而 ...
let "num = (( 0 && 1 ))"
echo $? # 1 ***
(( 200 || 11 )) # 逻辑或
echo $? # 0 ***
# ...
let "num = (( 200 || 11 ))"
echo $num # 1
let "num = (( 200 || 11 ))"
echo $? # 0 ***
(( 200 | 11 )) # 按位或
echo $? # 0 ***
# ...
let "num = (( 200 | 11 ))"
echo $num # 203
let "num = (( 200 | 11 ))"
echo $? # 0 ***
# "let" 结构的退出状态与双括号算术扩展的退出状态是相同的。
注意,双括号算术扩展表达式的退出状态码不是一个错误的值。算术表达式为0,返回1;算术表达式不为0,返回0。
if不仅可以用来测试括号内的条件表达式,还可以用来测试其他任何命令。
感谢 Stéphane Chazelas 提供了后两个例子。
样例 7-1. 什么才是真?
练习:理解 样例 7-1
如果把 if 和 then 写在同一行时,则必须在 if 语句后加上一个分号来结束语句。因为 if 和 then 都是 关键字。以关键字(或者命令)开头的语句,必须先结束该语句(分号;),才能执行下一条语句。
Else if 与 elif
elif
elif 是 else if 的缩写。可以把多个 if/then 语句连到外边去,更加简洁明了。
if test condition-true 完全等价于 if [ condition-true ]。当语句开始执行时,左括号 [ 是作为调用 test 命令的标记,而右括号则不严格要求,但在新版本的 Bash 里,右括号必须补上。
test 命令是 Bash 的 内建命令,可以用来检测文件类型和比较字符串。在 Bash 脚本中,test 不调用 sh-utils 包下的文件 /usr/bin/test。同样,[ 也不会调用链接到 /usr/bin/test 的 /usr/bin/[ 文件。
如果你想在 Bash 脚本中使用 /usr/bin/test,那你必须把路径写全。
样例 7-2. test,/usr/bin/test,[] 和 /usr/bin/[ 的等价性
在 Bash 里,[[ ]] 是比 [ ] 更加通用的写法。其作为扩展test 命令从 ksh88 中被继承了过来。
在 [[ 和 ]] 中不会进行文件名扩展或字符串分割,但是可以进行参数扩展和命令替换。
使用 [[...]] 代替 [...]可以避免很多逻辑错误。比如可以在 [[]] 中使用 &&,||,< 和 > 运算符,而在 [] 中使用会报错。
在 [[]] 中会自动执行八进制和十六进制的进制转换操作。
语法上并不严格要求在 if 之后一定要写 test 命令或者测试结构([] 或 [[]])。
if COMMAND 的退出状态就是COMMAND 的退出状态。
同样的,测试括号也不一定需要与 if 一起使用。其可以同 列表结构 结合而不需要 if。
(( )) 结构 扩展和执行算术表达式。如果执行结果为0,其返回的 退出状态码 为1(假)。非0表达式返回的退出状态为0(真)。这与上述所使用的 test 和 [ ] 结构形成鲜明的对比。
样例 7-3. 使用 (( )) 进行算术测试
Last updated
Was this helpful?