Shell 条件测试用于根据不同的条件执行不同的代码块。常见的条件测试包括文件测试、字符串比较、数值比较和逻辑组合。
一、测试命令
在 Shell 中,条件测试可以通过以下两种方式实现:
1、test 命令
test 条件表达式
2、[ ] 或 [[ ]]
[ 条件表达式 ] # 传统 test 命令的简写(注意空格)
[[ 条件表达式 ]] # Bash 增强版(支持更多功能,如&&、||、正则匹配)
二、测试详解
1、文件测试
检查文件或目录的状态:
测试条件 | 说明 |
---|---|
-e file | 文件/目录是否存在 |
-f file | 是否是普通文件(非目录、设备等) |
-d file | 是否是目录 |
-s file | 文件是否非空(大小 > 0) |
-r file | 当前用户是否有读权限 |
-w file | 当前用户是否有写权限 |
-x file | 当前用户是否有执行权限 |
-L file | 是否是符号链接 |
file1 -nt file2 | file1 是否比 file2 新(修改时间) |
file1 -ot file2 | file1 是否比 file2 旧 |
示例:
[root@lichu ~]# test -d /home
[root@lichu ~]# echo $?
0
[root@lichu ~]# test -d /home11111
[root@lichu ~]# echo $?
1
[root@lichu ~]# [ ! -d /ccc ] && mkdir /ccc # 当前一个命令成功,后一个命令才执行
[root@lichu ~]# [ -d /ccc ] || mkdir /ccc # 当前一个命令失败,后一个命令才执行
[root@lichu ~]# vim test01.sh
if [[ -f "/etc/passwd" ]]; then
echo "文件存在"
fi
[root@lichu ~]# vim test02.sh
if [ -d "/tmp" ]; then
echo "/tmp 是目录"
fi
2、字符串比较
测试条件 | 说明 |
---|---|
-z "$str" | 字符串是否为空(长度为 0) |
-n "$str" | 字符串是否非空(长度 > 0) |
"$str1" = "$str2" | 字符串是否相等(== 也可用) |
"$str1" != "$str2" | 字符串是否不相等 |
示例:
[root@lichu ~]# vim test03.sh
read -p "Input username: " name
if [[ -z "$name" ]]; then
echo "输入的名字为空"
else
echo "你输入的名字为 $name"
fi
[root@lichu ~]# vim /home/test04.sh # 找一个普通用户也能读取的位置
if [[ "$USER" == "root" ]]; then # 字符串比较一定要使用双引号
echo "你当前是root,有安装权限"
else
echo "你当前不是root,没有安装权限"
fi
[root@lichu ~]# /home/test04.sh # root用户执行
你当前是root,有安装权限
[tom@lichu ~]$ /home/test04.sh # 普通用户执行
你当前不是root,没有安装权限
[root@lichu ~]# vim /home/test05.sh # 找一个普通用户也能读取的位置
if [[ "$USER" != "root" ]]; then # 字符串比较一定要使用双引号
echo "当前不是root,没有安装权限,退出"
exit # exit直接退出整个脚本
fi
echo "开始安装软件........."
再测试字符字符串空和非空
[root@lichu ~]# var1=111 # var1定义,有值
[root@lichu ~]# var2= # var2定义,空值
[root@lichu ~]# # var3未定义
[root@lichu ~]# echo ${#var1} # 获得变量值的长度
3
[root@lichu ~]# echo ${#var2}
0
[root@lichu ~]# echo ${#var3}
0
[root@lichu ~]# [ -z "$var1" ];echo $? # 是否为空
1
[root@lichu ~]# [ -z "$var2" ];echo $?
0
[root@lichu ~]# [ -z "$var3" ];echo $?
0
[root@lichu ~]# [ -n "$var1" ];echo $?
0
[root@lichu ~]# [ -n "$var2" ];echo $?
1
[root@lichu ~]# [ -n "$var3" ];echo $?
1
错误的案例:var2变量未被定义
[root@lichu ~]# [ -z $var2 ];echo $?
0
[root@lichu ~]# [ -n $var2 ];echo $?
0
正确的案例:var2变量未被定义
[root@lichu ~]# [ -n "$var2" ];echo $?
1
[root@lichu ~]# [ -z "$var2" ];echo $?
0
[root@lichu ~]# [[ -n $var2 ]];echo $?
1
[root@lichu ~]# [[ -z $var2 ]];echo $?
0
- 字符串比较建议用
[[ ]]
,避免[ ]
中的变量未加引号导致的问题。 =
和==
在[[ ]]
中作用相同,但在[ ]
中==
可能不兼容。
3、数值比较
用于比较整数(不支持浮点数)
测试条件 | 说明 |
---|---|
$num1 -eq $num2 | 是否相等(equal) |
$num1 -ne $num2 | 是否不相等(not equal) |
$num1 -gt $num2 | 是否大于(greater than) |
$num1 -ge $num2 | 是否大于等于(greater or equal) |
$num1 -lt $num2 | 是否小于(less than) |
$num1 -le $num2 | 是否小于等于(less or equal) |
示例:
[root@lichu ~]# vim test06.sh
#!/bin/bash
read -p "输入你的年龄: " age
if [[ $age -lt 18 ]]; then
echo "未成年"
else
echo "已成年"
fi
获得根分区的使用率:
[root@lichu ~]# df |grep "/$" |awk '{print $5}' |awk -F"%" '{print $1}'
25
[root@lichu ~]# disk_use=$(df |grep "/$" |awk '{print $5}' |awk -F"%" '{print $1}')
[root@lichu ~]# [[ $disk_use -gt 60 ]] && echo "war....."
[root@lichu ~]# [[ $disk_use -gt 10 ]] && echo "war....."
war.....
[root@lichu ~]# vim test07.sh # 作业
判断磁盘的使用率,如果超过90%则报警
获得当前用户的UID:
[root@lichu ~]# id -u
0
[root@lichu ~]# [ $(id -u) -eq 0 ] && echo "当前是超级用户"
当前是超级用户
[alice@lichu ~]$ [ $UID -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户"
you不是超级用户
[root@lichu ~]# vim test08.sh # 作业
判断当前用户是否是root
C语言风格的数值比较
[root@lichu ~]# ((1<2));echo $?
0
[root@lichu ~]# ((1==2));echo $?
1
[root@lichu ~]# ((1>2));echo $?
1
[root@lichu ~]# ((1>=2));echo $?
1
[root@lichu ~]# ((1<=2));echo $?
0
[root@lichu ~]# ((1!=2));echo $?
0
[root@lichu ~]# ((`id -u`>0));echo $?
1
[root@lichu ~]# (($UID==0));echo $?
0
4、逻辑组合
用于组合多个条件:
测试条件 | 说明 |
---|---|
! 条件 | 逻辑非(条件取反) |
条件1 && 条件2 | 逻辑与(条件1 且 条件2) |
条件1 || 条件2 | 逻辑或(条件1 或 条件2) |
示例:
# 使用 [[ ]](推荐)
[root@lichu ~]# vim test09.sh
if [[ -f "/etc/passwd" && -r "/etc/passwd" ]]; then
echo "文件存在且可读"
fi
[root@lichu ~]# vim test10.sh
# 使用 [ ](需要 -a、-o)
if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then
echo "文件存在且可读"
fi
[[ ]]
支持&&
和||
,更直观[ ]
必须用-a
(and)和-o
(or)
5、正则匹配(先了解)
[[ ]]
支持 =~
进行正则匹配:
[root@lichu ~]# vim test11.sh
#!/bin/bash
#判断用户输入的是否是数字
read -p "请输入一个数值: " num
if [[ ! "$num" =~ ^[0-9]+$ ]];then
echo "你输入的不是数字,程序退出!!!"
exit
fi
echo "脚本其它代码....."
[root@lichu ~]# vim test12.sh # 先复制用
#!/bin/bash
#判断用户输入的是否是数字
read -p "请输入一个数值: " num
while :
do
if [[ $num =~ ^[0-9]+$ ]];then
break
else
read -p "不是数字,请重新输入数值: " num
fi
done
echo "你输入的数字是: $num"
echo "开始执行其它代码......"
6、命令返回值测试
检查上一条命令是否成功:
[root@lichu ~]# vim test13.sh
if id tom &>/dev/null; then
echo "tom用户存在"
fi
[root@lichu ~]# vim test14.sh
id tom &>/dev/null
if [[ $? -eq 0 ]]; then
echo "tom用户存在"
fi
三、注意事项
1、优先使用 [[ ]],功能更强大且不易出错
2、变量引用加双引号(如 “$var”),避免空变量或空格导致的问题
3、数值比较用 -eq、-lt,字符串比较用 ==、!=
四、有意思的
() 子shell中执行 (cd /home;pwd)
(()) 数值比较,运算 C语言
$() 命令替换
$(()) 整数运算
[] 传统的条件测试,同test
[[]] 升级版的条件测试,支持正则 =~
$[] 整数运算
{} 生成组合touch file{1,2}.txt,生成序列touch file{a..f}.txt
${} 变量引用