条件测试语句
语法格式
- 格式1
test expression
- 格式2
[ expression ]
- 格式3
[[ expression ]]
[
是一条命令,它与test
是等价的。在其中的表达式应是它的命令行参数,所以字符串比较操作符>
与<
必须转义,否则就变成 重定向向操作符了1
2
3
4
5[user1@study ~]$ [ 3 \> 2 ] && echo yes || echo no
yes
[user1@study ~]$ [ 1 \> 2 ] && echo yes || echo no
no
[user1@study ~]$- 格式1
[[]]
是是扩展的 test
命令,用 [[]]
测试结构比用 []
更能防止脚本里的许多逻辑错误。&&
、||
、 <
、>
操作符能够正常存在于 [[ ]]
中,但不能在 []
中出现。
1 | [user1@study ~]$ [[ "2" = "2" && "3" = "3" ]] && echo yes || echo no |
在 [[]]
中可以使用通配符进行模式匹配
1 | [user1@study ~]$ [[ abc123 = abc* ]] && echo yes || echo no |
在 [[]]
中使用 =~
时支持 shell 的正则表达式
1 | [user1@study ~]$ [[ '12345' =~ [0-9]{5} ]] && echo yes || echo no |
需要注意,不管是 [[]]
还是 []
,最里面的中括号旁边都必须保留一个空格,否则是语法错误
1 | [user1@study ~]$ [3=3] && echo yes || echo no |
算术运算符
运算符 | 说明 | |
---|---|---|
+ | 加法 | `expr $a + $b` |
- | 减法 | `expr $a - $b` |
* | 乘法 | `expr $a * $b` |
/ | 除法 | `expr $a / $b` |
% | 取余 | `expr $a % $b` |
= | 赋值 | a=$b 将变量b的值赋给 a |
== | 相等。用于比较两个整数,相同则返回 true | [ $a == $b ] 返回 false。 |
!= | 不等。用于比较两个整数,不同则返回 true | [ $a != $b ] 返回 true。 |
算术运算
要对整数进行关系运算可以下面几种方式实现
let
算术运算表达式
1 | [user1@study ~]$ a=1; b=2 |
$[算术运算表达式]
1 | [user1@study ~]$ a=1; b=2 |
$((算术运算表达式))
1 | [user1@study ~]$ a=1; b=2 |
expr
算术运算表达式,要注意 expr
的表达式中各操作符及运算符之间要有空格,且要使用命令替换
1 | [user1@study ~]$ a=1; b=2 |
也可以使用 shell 的算术运算符 (())
进行计算,事实上 (())
比 let
、expr
会更高效,最建议使用这种方式
1 | [user1@study ~]$ a=1; b=2 |
关系运算符
关系运算符只支持整数,不支持字符串,除非字符串的值是整数
运算符 | 说明 | 举例 |
---|---|---|
-eq | 测试两个整数是否相等,相等返回 true | [ $a -eq $b ] |
-ne | 测试两个整数是否相等,不相等返回 true | [ $a -ne $b ] |
-gt | 测试左边的整数是否大于右边的,如果是,则返回 true | [ $a -gt $b ] |
-lt | 测试左边的整数是否小于右边的,如果是,则返回 true | [ $a -lt $b ] |
-ge | 测试左边的整数是否大等于右边的,如果是,则返回 true | [ $a -ge $b ] |
-le | 测试左边的数是否小于等于右边的,如果是,则返回 true | [ $a -le $b ] |
逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true | [ ! 0 -ne 0 ] 返回true |
-o | 或运算,有一个表达式为 true 则返回 true | [ $a -lt 20 -o $b -gt 100 ] |
-a | 与运算,两个表达式都为 true 才返回 true | [ $a -lt 20 -a $b -gt 100 ] |
[ expression1 ] && [ expression2 ]
等价于 [ expression1 -a expression2 ]
1 | [user1@study ~]$ [ "abc" = "abc" -a "bcd" = "efg" ] && echo yes || echo no |
字符串运算符
运算符 | 说明 | 举例 |
---|---|---|
> | 测试前面字符串的ASCII码比后面的大 | [[ “abc” > “ABC” ]] |
< | 测试前面字符串的ASCII码比后面的小 | [[ “abc” < “ABC” ]] |
= | 检测两个字符串是否相等,也可使用== | [ “$a” = “$b” ] |
!= | 检测两个字符串是否相等,不相等返回 true | [ “$a” != “$b” ] |
=~ | 左侧的字符串是否能被右侧的正则表达式模式匹配 | “$char” =~ pattern |
-z | 检测字符串长度是否为0,为0返回 true | [ -z “$a” ] 或 test -z “$a” |
-n | 检测字符串长度是否为0,不为0返回 true | [ -n “$a” ] 或 test -n “$a” |
str | 检测字符串是否不为空,不为空返回 true | [ “$a” ] 或 test “$a” |
从 Bash 3.2 版本开始,正则表达式和globbing表达式都不能用引号包裹。若表达式里有空格,则可以把它存储到一个变量里:
1 | a="a b+" |
做个练习,比较一下不同的运算符及其作用
1 | a="abc123" |
文件测试运算符
运算符 | 说明 | 举例 |
---|---|---|
-a file | 测试文件(包括目录)是否存在;同-e;-a处于弃用状态 | [ -a $file ] |
-b file | 测试文件是否是块设备文件 | [ -b $file ] |
-c file | 测试文件是否是字符设备文件; | [ -b $file ] |
-d file | 测试文件是否是目录; | [ -d $file ] |
-e file | 测试文件(包括目录)是否存在; | [ -e $file ] |
-f file | 测试文件是否是普通文件(既不是目录,也不是设备文件); | [ -f $file ] |
-g file | 测试文件是否设置了 SGID 位; | [ -g $file ] |
-G file | 文件的group-id是否与你的相同 | [ -G $file ] |
-h file | 测试文件是否是符号链接文件;同-L; | [ -h /bin/awk ] |
-k file | 测试文件是否设置了粘着位(Sticky Bit); | [ -k $file ] |
-L file | 测试文件是否是符号链接文件;同-h; | [ -h /bin/awk ] |
-N file | 测试文件从文件上一次被读取到现在为止,是否被修改过 | [ -N $file ] |
-O file | 测试文件的owner是否为当前用户 | [ -O $file] |
-p file | 测试文件是否是管道文件; | [ -p $file ] |
-r file | 测试文件是否可读; | [ -r $file ] |
-s file | 测试文件是否存在且不为空(文件大小是否大于0)。 | [ -s $file ] |
-u file | 测试文件是否设置了 SUID 位; | [ -u $file ] |
-w file | 测试文件是否可写; | [ -w $file ] |
-x file | 测试文件是否可执行; | [ -x $file ] |
f1 -nt f2 | 测试文件f1是否比文件f2新 | |
f1 -ot f2 | 测试文件f1是否比文件f2旧 | |
f1 -ef f2 | 测试文件f1和文件f2是否是相同文件的硬链接 |