shell常用运算符
1. 比较运算符
1.1 整数比较运算符
下表列出了常用的比较运算符,注意,表达式成立返回的是0,不成立返回的是1,相当于是返回的状态码,以下的例子都是在交互式shell中直接执行,然后可用echo $?来获取式子是否成立,假定变量a=1,b=2(只能是整数):
运算符 | 说明 | 举例 |
---|---|---|
-eq | equals 检测两个数是否相等 | [ $a -eq $b ] |
-ne | not equals 检测两个数是否不相等 | [ $a -ne $b ] |
-gt | greater than 检测左边的数是否大于右边 | [ $a -gt $b ] |
-lt | lower than 检测左边的数是否小于右边 | [ $a -lt $b ] |
-ge | greater equals 左边的数是否大于等于右边 | [ $a -ge $b ] |
-le | lower equals 左边的数是否小于等于右边 | [ $a -le $b ] |
< | (( a < a< a<b)) | |
<= | (( a < = a<= a<=b)) | |
> | (( a > a> a>b)) | |
>= | 注意这边都是用的双小括号 | (( a > = a>= a>=b)) |
== | (( a = = a== a==b)) | |
!= | (( a ! = a!= a!=b)) |
Tips:
-
这些运算符都只支持整数,不支持小数与字符串,除非字符串的值都是整数数字(
(("1"=="1"))
与[ "123" -eq "123" ]
是可行的); -
一般都是在.sh脚本文件结合if来使用
if [ $a -eq $b ]
或是if (($a==$b))
; -
注意各自的格式,使用
[ ]
那变量与符号与中括号之间都必须要有空格的。
1.2 字符串比较运算符
可以比较2个变量,变量的类型可以为数字(整数、小数)与字符串。
语法:字符串比较可以使用[[]]
和[]
两种方式,假定变量a=“abc”,b=“efg”,下表列出了常用字符串运算符。
运算符 | 说明 | 举例 |
---|---|---|
== 或 = | 用于比较两个字符串或数字相等, | [ 1.1 == 1.1 ] [ 1.1 = 2 ] [[ $a == $b ]] [[ $a = $b ]] |
!= | 一样成立返回状态码0 | [ $a != $b ] [[ $a != $b ]] |
< | 不成立就是返回状态码1 | [ $a \< $b ] [[ $a < $b ]] |
> | 没有>=,用逻辑||、&&去连接两个表达式 | [ “abc” \> “abc” ] [[ $a > $b ]] |
-z | 检测字符串长度是否为0 | [ -z “” ] 得0,成立 |
-n | 检测字符串长度是否不为0 | [ -n “” ] 得1,不成立 |
$ | 检测字符串是否不为空 | aa="";[ $aa ];echo $? 得到的是1 bb=123;[ $bb ];echo $? 得到的时候0 |
Tips:
- 单个
[ ]
使用<
、>
时一定要加转义符\
,不然结果可能不正确,而双[[ ]]
是不需要的; - 特别注意
[[ ]]
是没有大于等于这种写法的- [[ “abc” < “efg” || “abc” == “abc” ]] 这就做到了
<=
- [[ “abc” < “efg” || “abc” == “abc” ]] 这就做到了
[[]]和[]的区别及
-
[[]]不会有word splitting,而[]会有word splitting发生
a="a" b="a b c" [[ $a == $b ]]; echo $? # 得到的是1,没问题 [ $a == $b ]; echo $? # 这会直接报错,说参数太多,这是因为[]会把$b通过空格分隔开就相当于3个参数了
-
[[]]中是不需要转义符的,而[]中部分是要转义符的。
1.3 总结,必看这
[[ ]]
:无脑使用,无论是整数(全是整数的话还是用(( ))
,[[]]里面是没有>=、<=的)、小数还是字符串都可以,判定相等有==
和=
,且不会有单词空格的分割,也不需要转义符号;- 针对字符串还有一个
[ ]
,部分需要转义,有空格分割; - 针对整数还有一个(()),千万别用到字符串比较去了,不会报错,但结构基本都是有问题的,这个判等只有
==
,在这里=
是赋值;
整数也还能用[ ]
,它就是搭配字母那种的运算符,如[ 123 -eq 123 ]
这样使用。
总之:无论是整数、小数还是字符串,无脑用[[ ]]
就对了。但是注意下面一节布尔运算符又要求只能用[ ]
。
2. 布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,取反 | |
-o | or 或运算 | |
-a | and 与运算 |
Tips:
- 注意布尔运算符放在
[ ]
中使用(注意转义),或与test
命令配合使用才有效; - 布尔运算常与test命令搭配使用,可看[这里](#5.5 test)。
下面是在shell交互式环境中进行:
[ 1 \> 2 ]; echo $? # 得1,注意一定要有空格和转义符
[ ! 1 \> 2 ]; echo $? # 得0
[ 1 \> 2 -o 1 == 1 ] # 得 0
[ 1 \> 2 -a 1 == 1 ] # 得 1
3. 逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 and | [[ 表达式1 && 表达式2 ]] |
|| | 逻辑的 or | [[ 表达式1 || 表达式2 ]] |
! | 逻辑非 | [[ ! 表达式 ]] |
Tips:
- 使用
&&
和||
必须在[[ ]]
或(( ))
中才有效,否则报错; !
可以在[ ]
、[[ ]]
中使用,但不可以在(( ))
中使用。
总之:在使用! && ||这样符号逻辑连接的时候,尽量使用[[ ]]
;如果要使用 -a及-o这样字母的逻辑连接时,必须使用[ ]
。
4. 文件测试运算符
文件类型介绍:
-
-
:普通文件; -
d
:文件夹; -
l
:链接文件; -
b
:块设备文件,比如计算机硬盘ls -l /dev | grep sda
; -
c
:字符设备文件,比如计算机的usb文件ls -l /dev | grep usb
; -
p
:管道文件。
文件测试运算符用于检测文件的何种属性,如下表:
操作符 | 说明 |
---|---|
-d file | 检测文件是否是目录 |
-f file | 检测文件是否是普通文件 |
-r file | 检测文件是否可读 |
-w file | 检测文件是否可写 |
-x file | 检测文件是否可执行 |
-s file | size,检测文件是否不为空(大小是否大于0) |
-e file | exists,检测文件(夹)是否存在 |
file1 -nt file2 | new than,file1是否比file2新 |
file1 -ot file2 | old than,file1是否比file2旧 |
-b file | 是否是块设备文件 |
-c file | 是否是字符设备文件 |
-g file | 检测文件是否设置了SGID位 |
-k file | 检测是否设置了粘着位(Sticky Bit) |
-p file | 是否是有名管道文件 |
-u file | 检测是否设置了SUID位 |
-S | 判断某文件是否socket |
-L | link,检测文件是否存在并且是一个符号链接 |
示例,一个.sh脚本文件:
#!/bin/bash
file1="/root/456.txt"
file2="/root/123.txt"
if [[ -e $file1 ]]
then
echo "文件存在"
else
echo "文件不存在"
fi
#***********************
if [[ -s $file1 ]]
then
echo "文件不为空"
else
echo "文件为空"
fi
#***********************
if [ $file1 -nt $file2 ]
then
echo "文件1比较新"
else
echo "文件2比较新"
fi
一般我们是用[[ ]]
,然后[ ]
也是可以的。
这是对文件检测的操作,如果对输入的数据(字符串)也有检测要求,那么就是看上面的1.2 字符串比较运算符。