大家好呀!今天简单聊一聊Shell条件判断相关的内容,如文件比较、整数及字符串之间的判断、多重条件判断等。

1、语法格式

三种语法格式:

1)test 条件表达式

test -e file:文件file存在则为真

2)[ 条件表达式 ]

[ -d /shell01/dir1 ]:目录dir1存在则为真
[ ! -d /shell01/dir1 ]:目录dir1不存在则为真

3) [[ 条件表达式 ]],支持正则

[[ -f /shell01/1.sh ]]:文件1.sh存在且为普通文件,则为真

注意中括号前后都要有空格

通过man test查看对应参数及其用法,0为真,1为假。与通常的1真0假不同。

2、条件判断相关参数

2.1 文件存在与否判断

1)常用

1
2
3
4
-e	是否存在(不管是文件还是目录,只要存在,条件就成立)
-f 是否为普通文件
-d 是否为目录
-s 判断文件是否有内容(大小),非空则为真

!表示取反,eg:-s表示非空,! -s 表示空文件。-d表示目录存在,! -d表示目录不存在。


2)其他

1
2
3
4
5
-S	socket
-p pipe
-c character
-b block
-L 软link

2.2 文件权限相关判断

1
2
3
4
5
6
-r	当前用户对其是否可读
-w 当前用户对其是否可写
-x 当前用户对其是否可执行
-u 是否有suid
-g 是否sgid
-k 是否有t位

$?:上一条命令执行后返回的状态。echo $?:输出上一条命令执行后返回的状态。

2.3 两个文件的比较判断

常见的参数有-nt、-ot、-ef,用法如下。

nt(newer than),ot(older than),ef(equal file)

1
2
3
4
5
6
7
8
# 1.比较file1是否比file2新
test file1 -nt file2
# 2.比较file1是否比file2旧
test file1 -ot file2
# 3.比较是否为同一个文件,或者用于判断硬链接,是否指向同一个inode
test file1 -ef file2
# 为file1文件建立链接file2(硬链接)
ln file1 file2

ln(link files)命令:为某一个文件在另外一个位置建立一个同步的链接。硬链接,无需重复占用磁盘空间。

硬链接相当于原文件的别名,软链接相当于原文件的快捷方式。

2.4 整数之间的判断

记住如下一些常见的英文首字母简写即可:

1
2
3
4
5
6
-eq:相等(equal)
-ne:不等(not equal)
-gt:大于(greater than)
-lt:小于(less than)
-ge:大于等于(greater equal)
-le:小于等于(less equal)

2.5 字符串之间的判断

1
2
-z:是否为空字符串   	字符串长度为0,就成立
-n:是否为非空字符串 只要字符串非空,就成立

字符串的比较判断,尽量加上引号作为整体。

将上述简单的写法应用到具体的变量中,如下

双引号”” :会把引号的内容当成整体来看待,允许通过$符号引用其他变量值

2.6 多重条件判断

逻辑判断符号:

1
2
-a  和 &&  	(and 逻辑与) 		两个条件同时满足,整个大条件为真
-o 和 || (or 逻辑或) 两个条件满足任意一个,整个大条件为真

eg:

1
2
3
4
5
6
7
# 1等于1 且 1不等于0,为真
[ 1 -eq 1 -a 1 -ne 0 ] 整个表达式为真
[ 1 -eq 1 ] && [ 1 -ne 0 ]

# 1等于1 或 1不等于1,为真
[ 1 -eq 1 -o 1 -ne 1 ] 整个表达式为真
[ 1 -eq 1 ] || [ 1 -ne 1 ]

&&:前面的表达式为真,才会执行后面的内容。||:前面的表达式为假,才会执行后面的内容

既有逻辑与(&&)又有逻辑或(||),从左往右依次判断,没有优先级之分。

总结:

1); && ||都可以用来分割命令或表达式
2); 完全不考虑前面的语句是否正确执行,都会执行;号后面的内容
3)&& 需要考虑&&前面的语句的正确性,前面语句正确执行才会执行&&后的内容;反之亦然。eg:make && make install
4)|| 需要考虑||前面的语句的非正确性,前面语句执行错误才会执行||后的内容;反之亦然。
5)如果&&和||一起出现,从左往右依次看,按照以上原则

3. eg

1)判断当前的登录用户是否为管理员

1
2
3
4
5
6
7
8
9
10
[root@server ~]# [ $(id -u) -eq 0 ] && echo "the user is admin"
[root@server ~]$ [ $(id -u) -ne 0 ] && echo "the user is not admin"
[root@server ~]$ [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"

[root@server ~]# uid=`id -u`
[root@server ~]# test $uid -eq 0 && echo this is admin
[root@server ~]# [ $(id -u) -ne 0 ] || echo this is admin
[root@server ~]# [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin
[root@server ~]# su - stu1
[stu1@server ~]$ [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin


2)类C风格的数值比较

注:在(( ))中,=表示赋值;==表示判断

1
2
3
4
((1==2));echo $? # 1
((1<2));echo $? # 0
((2>=1));echo $? # 0
((2!=1));echo $? # 0

3)字符串比较

注:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断

1
2
3
4
5
6
a='hello world';b=world
[ "$a" = "$b" ];echo $?
[ "$a" != "$b" ];echo $?
[ "$a" !== "$b" ];echo $? # 错误
[ "$a" == "$b" ];echo $?
test "$a" != "$b";echo $?