比较运算符

整数比较运算符

比较方式 [](())

  • 方式1: [ 整数1 options 整数2 ]

    options: -eq -gt -ge -lt -le -ne

  • 方式2: ((整数1 options 整数2))

    option:< <= > >= == !=

    注意:判断等于不可以使用= ,等于在(())里面是赋值的含义

假设变量 a 为 1,变量 b 为 2:

运算符 说明 例子
-eq equals 检测两个数是否相等,相等返回 0, 否则返回1。 [ $a -eq $b ] 返回 1。
-ne not equals检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 0。
-gt greater than检测左边的数是否大于右边的,
是返回0, 否则1
[ $a -gt $b ] 返回 1。
-lt lower than检测左边的数是否小于右边的,
是返回0, 否则1
[ $a -lt $b ] 返回 0。
-ge greater equals检测左边的数是否大于等于右边的,
是返回0, 否则1
[ $a -ge $b ]返回 1。
-le lower equals检测左边的数是否小于等于右边的,
是返回0, 否则1
[ $a -le $b ]返回 0。
< 检测左边的数是否小于右边的,
是返回0, 否则1
(($a<$b)) 返回0
<= 检测左边的数是否小于等于右边的,
是返回0, 否则1
(($a<=$b)) 返回0
> 检测左边的数是否大于右边的,
是返回0, 否则1
(($a>$b)) 返回1
>= 检测左边的数是否大于等于右边的,
是返回0, 否则1
(($a>=$b)) 返回1
== 检测左边的数是否等于右边的,
是返回0, 否则1
(($a==$b)) 返回1
!= 检测左边的数是否不等于右边的,
是返回0, 否则1
(($a!=$b)) 返回0

整数比较运算符只支持整数,不支持小数与字符串,除非字符串的值是整数数字。
每个命令都有返回值,返回0代表成功,返回1代表失败。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/bash
a=1 b=2
echo "a=${a} b=${b}"
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b" # 输出这个
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b" # 输出这个
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b" # 输出这个
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b" # 输出这个
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b" # 输出这个
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b" # 输出这个
else
echo "$a -le $b: a 大于 b"
fi

if (($a > $b))
then
echo "$a > $b: a 大于 b"
else
echo "$a > $b: a 不大于 b" # 输出这个
fi
if (($a < $b))
then
echo "$a < $b: a 小于 b" # 输出这个
else
echo "$a < $b: a 不小于 b"
fi
if (($a >= $b))
then
echo "$a >= $b: a 大于或等于 b"
else
echo "$a >= $b: a 小于 b" # 输出这个
fi
if (($a <= $b))
then
echo "$a <= $b: a 小于或等于 b" # 输出这个
else
echo "$a <= $b: a 大于 b"
fi

输出:

字符串比较运算符

可以比较2个变量,变量的类型可以为数字(整数,小数)与字符串。
比较方式 [][[]]

  • 方式1: [ 变量1 options 变量2 ]

    options:< > == = !=

    <,> 需要转义,会发生word splitting

  • 方式2: [[ 变量1 options 变量2]]

    options:< > == = !=

    <,> 不需要转义,不会发生word splitting

word splitting:会将含有空格字符串进行分拆分割后比较

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
== 或 = 相等。用于比较两个字符串或数字,相同则返回 0。可以使用= [ $a == $b ]返回1
[ $a = $b ] 返回 1
[[ $a == $b ]] 返回1
[[ $a = $b ]] 返回1
!= 不相等。用于比较两个字符串或数字,不相同则返回 0。 [ $a != $b ] 返回 0
[[ $a != $b ]] 返回 0
< 小于, 用于比较两个字符串或数字, 小于返回0, 否则返回1 [ $a \< $b ] 返回 0
[[ $a < $b ]] 返回 0
> 大于, 用于比较两个字符串或数字, 大于返回0, 否则返回1 [ $a \> $b ] 返回 1
[[ $a > $b ]] 返回 1
-z zero,检测字符串长度是否为0,如果长度为0返回则返回0, 否则返回1。 [ -z $a ] 返回 false。
-n not zero,检测字符串长度是否不为 0,如果长度不为 0 则返回0, 否则返回1。 [ -n “$a” ] 返回 true。
$ 检测字符串是否不为空,不为空返回0, 为空返回1。 [ $a ] 返回 true。

注:字符串比较没有 <= 可以通过 [[ "a" < "b" && "a" == "b" ]]来实现。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash

a="hello" b="world" c=1 d=2
echo "a=${a},b=${b},c=${c},d=${d}"

if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b" # 输出这个
fi

if [ $a != $b ]
then
echo "$a != $b : a 不等于 b" # 输出这个
else
echo "$a != $b: a 等于 b"
fi

if [[ $a > $b ]]
then
echo "$a > $b : a 大于 b"
else
echo "$a > $b: a 不大于 b" # 输出这个
fi

if [ $a \> $b ]
then
echo "$a > $b : a 大于 b"
else
echo "$a > $b: a 不大于 b" # 输出这个
fi

if [[ $c > $d ]]
then
echo "$c > $d : c 大于 d"
else
echo "$c > $d: c 不大于 d" # 输出这个
fi

if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0" # 输出这个
fi

if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0" # 输出这个
else
echo "-n $a : 字符串长度为 0"
fi

if [ $a ]
then
echo "$a : 字符串不为空" # 输出这个
else
echo "$a : 字符串为空"
fi

输出:

[[]][] 的区别

区别1:[]会将含有空格字符串进行分拆分割后比较,而[[]]不会:

通过 $? 获取上一个命令的退出状态,0代表成功,1代表失败。

区别2:[] 需要对 <,> 转义 , 格式为 [ 字符串1 \< 字符串2 ],而 [[]] 不需要转义,格式为 [[ 字符串1 < 字符串2 ]]

比较可知:[[ 表达式 ]] 即可以实现数字和字符串比较,并且不需要转义,不会word splitting,推荐使用[[]]作为比较运算符。

布尔运算符

布尔运算符用于对布尔值进行运算。

运算符 说明 举例
! 非运算,取反, 表达式为 true 则返回 false,
否则返回 true。
[ ! 表达式 ] 取反。
-o or 或运算,有一个表达式为 true 则返回 true。 [ 表达式1 -o 表达式2 ]
-a and 与运算,两个表达式都为 true 才返回 true。 [ 表达式1 -a 表达式2 ]

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
a=1 b=2

if [ $a -lt 2 -a $b -gt 10 ]
then
echo "$a 小于 2 且 $b 大于 10 : 返回 true"
else
echo "$a 小于 2 且 $b 大于 10 : 返回 false" # $b -gt 10不成立, 输出这个表达式
fi

if [ $a -lt 10 -o $b -gt 10 ]
then
echo "$a 小于 10 或 $b 大于 10 : 返回 true" # $a -lt 10 成立, 输出这个表达式
else
echo "$a 小于 10 或 $b 大于 10 : 返回 false"
fi

if [ ! $a -gt $b ]
then
echo "$a 大于 $b 取反 : 返回 true"
else
echo "$a 大于 $b 取反 : 返回 false" # $a -gt $b 为true , 取反为false, 输出这个表达式
fi

注:布尔运算符必须与[]test 命令一起使用才有效。

逻辑运算符

逻辑运算符包括:逻辑非 ! 、逻辑与 && 、逻辑或 ||

运算符 说明 举例
&& 逻辑的 AND [[ 表达式1 && 表达式2 ]]
|| 逻辑的 OR [[ 表达式1 || 表达式2 ]]
! 逻辑非 [[ ! 表达式 ]]

注:使用 &&|| 的运算符必须放在 [[]](())中才有效,否则报错。而!既表示布尔运算符的非运算也表示逻辑运算符的逻辑非,所以它即可以用在[],也可以用在[[]]中,但!不可以用在(())中。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

a=1 b=2

if [[ $a -lt 10 && $b -gt 10 ]]
then
echo "返回 true"
else
echo "返回 false" # $b -gt 10 不成立, 输出false
fi

if [[ $a -lt 10 || $b -gt 10 ]]
then
echo "返回 true" # $a -lt 10 成立, 输出true
else
echo "返回 false"
fi

布尔运算符只能用在[]或配合test命令,而逻辑运算符用在[[]](())!较特殊,不可用在(())中。

文件测试运算符

文件测试运算符用于检测文件的相关属性。linux系统文件类型主要有:

  • -:普通文件
  • d:目录文件
  • l:链接文件
  • b:块设备文件
  • c:字符设备文件
  • p:管道文件

属性检测描述如下:

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ]
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ]
-d file directory, 检测文件是否是目录,如果是,则返回 true。 [ -d $file ]
-f file file, 检测文件是否是普通文件(既不是目录,也不是设备文件)
,如果是,则返回 true。
[ -f $file ]
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ]
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,
则返回 true。
[ -k $file ]
-p file 检测文件是否是有名管道文件,如果是,则返回 true。 [ -p $file ]
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ]
-r file read,检测文件是否可读,如果是,则返回 true。 [ -r $file ]
-w file write,检测文件是否可写,如果是,则返回 true。 [ -w $file ]
-x file execute, 检测文件是否可执行,如果是,则返回 true。 [ -x $file ]
-s file size, 检测文件是否为空(文件大小是否大于0)
,不为空返回 true。
[ -s $file ]
-e file exists, 检测文件(包括目录)是否存在,如果是,
则返回 true。
[ -e $file ]
file1 -nt file2 new than(nt), file1是否比file2新。 [ file1 -nt file2 ]
file1 -ot file2 old than(ot), file1是否比file2旧。 [ file1 -ot file2 ]
-S file 判断某文件是否 socket。 [ -S file ]
-L file 检测文件是否存在并且是一个符号链接。 [ -L file ]

文件测试运算符既可以用[ options 文件路径字符串],也可以用[[ options 文件路径字符串 ]]

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/bash

file="/root/operation1.sh"
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件是普通文件"
else
echo "文件是特殊文件"
fi
if [ -s $file ]
then
echo "文件不是空"
else
echo "文件是空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
if [ -d $file ]
then
echo "文件是目录"
else
echo "文件不是目录"
fi

file2="/root/operation2.sh"
if [ file -nt file2 ]
then
echo "operation1.sh文件比operation2.sh文件新"
else
echo "operation1.sh文件不比operation2.sh文件新"
fi