条件测试
Shell 条件测试
格式 1: test 条件表达式 格式 2: [ 条件表达式 ] 格式 3: [[ 条件表达式 ]]
具体参数说明可以通过 man test
进行查看
文件测试
[ 操作符 文件或目录 ]
[ -b FILE ]
FILE存在而且是块设备文件,则为True
[ -c FILE ]
FILE存在而且是字符文件,则为True
[ -d FILE ]
FILE存在而且是目录,则为True
[ -e FILE ]
FILE存在,则为True
[ -f FILE ]
FILE存在而且是普通文件,则为True
[ -g FILE ]
FILE存在而且设置了SGID位,则为True
[ -k FILE ]
FILE存在而且设置了粘着位,则为True
[ -L FILE ]
FILE存在而且是符号链接文件,则为True -L 相当于 -h
[ -p FILE ]
FILE存在而且是管道文件,则为True
[ -r FILE ]
FILE存在而且【当前用户】对该文件有读权限,则为True
[ -w FILE ]
FILE存在而且【当前用户】对该文件有写权限,则为True
[ -x FILE ]
FILE存在而且【当前用户】对该文件有执行权限,则为True
[ -u FILE ]
FILE存在而且设置了SUID位,则为True
[ FILE1 -nt FILE2 ]
FILE1比FILE2新(指的是修改时间modification date),则为True
[ FILE1 -ot FILE2 ]
FILE1比FILE2旧(指的是修改时间modification date),则为True
数值比较
[ 整数 1 操作符 整数 2 ]
[ num1 -eq num2 ]
num1 等于num2,则为True
[ num1 -ne num2 ]
num1 不等于num2,则为True
[ num1 -lt num2 ]
num1 小于num2,则为True
[ num1 -le num2 ]
num1 小于或者等于num2,则为True
[ num1 -gt num2 ]
num1 大于num2,则为True
[ num1 -ge num2 ]
num1 大于或者等于num2,则为True
C 语言风格的数值比较
# 小于 [root@yangs ~]# ((1<2));echo $? 0 # 等于 [root@yangs ~]# ((1==2));echo $? 1 # 大于 [root@yangs ~]# ((1>2));echo $? 1 # 大于等于 [root@yangs ~]# ((1>=2));echo $? 1 # 小于等于 [root@yangs ~]# ((1<=2));echo $? 0 # 不等于 [root@yangs ~]# ((1!=2));echo $? 0 # 命令执行结果是否大于0 [root@yangs ~]# ((`id -u`>0));echo $? 1 # UID是否等于0 [root@yangs ~]# (($UID==0));echo $? 0
字符串比较
注意
双引号的使用
[ -z string ]
字符串string长度为零,则为True
[ -n string ]
字符串string长度非零,则为True
[ string1 = string2 ]
string1与 string2相同,则为真
[ string1 != string2 ]
string1与 string2不同,则为真
测试条件之间的逻辑关系
条件测试中的测试条件之间的逻辑关系
( EXPRESSION )
判断当前条件EXPRESSION是否为真
逻辑与
EXPRESSION1 -a EXPRESSION2
判断条件EXPRESSION1和EXPRESSION2是否同时为真
逻辑或
EXPRESSION1 -o EXPRESSION2
判断条件EXPRESSION1和EXPRESSION2是否其中一个为真:
EXPRESSION1为真,则不判断EXPRESSION2
EXPRESSION1为假,则判断EXPRESSION2的真假
逻辑非
! EXPRESSION
判断当前条件EXPRESSION是否为假
示例
数值比较
例1
磁盘使用率检查
# 编写脚本 [root@hadoop04 shell]# vim disk_use.sh #!/usr/bin/bash red_col="\e[31m" green_col="\e[32m" reset_col="\e[0m" disk_use=`df -Th | grep "/$" | awk '{print $(NF-1)}' | awk -F "%" '{print $1}'` if [ ${disk_use} -ge 90 ];then echo -e "${red_col}disk use is dangerous,current value is ${disk_use}%${reset_col}" else echo -e "${green_col}disk use is healthy,current value is ${disk_use}%${reset_col}" fi # 执行脚本 [root@hadoop04 shell]# bash disk_use.sh disk use is healthy,current value is 14%
例2
磁盘使用率检查,发送邮件通知(正常或者异常都发送)
# 编写脚本 [root@hadoop04 shell]# vim disk_use_mail.sh #!/usr/bin/bash disk_use=`df -Th | grep "/$" | awk '{print $(NF-1)}' | awk -F "%" '{print $1}'` if [ ${disk_use} -ge 90 ];then echo "`date '+%F %H:%M:%S'` disk use is dangerous,current value is ${disk_use}%" | mail -s "disk use is too high" alice else echo "`date '+%F %H:%M:%S'` disk use is healthy,current value is ${disk_use}%" | mail -s "disk use is healthy" alice fi # 执行脚本 [root@hadoop04 shell]# bash disk_use_mail.sh # 切换到alice用户 [root@hadoop04 ~]# su - alice # 查收邮件 [alice@hadoop04 ~]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/alice": 1 message > 1 root Sun Dec 8 11:21 19/681 "disk use is healthy" # 输入想要查看的邮件编号,此处为1 & 1 Message 1: From root@hadoop04.localdomain Sun Dec 8 11:21:17 2019 Return-Path: <root@hadoop04.localdomain> X-Original-To: alice Delivered-To: alice@hadoop04.localdomain Date: Sun, 08 Dec 2019 11:21:17 +0800 To: alice@hadoop04.localdomain Subject: disk use is healthy User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: root@hadoop04.localdomain (root) Status: RO 2019-12-08 11:21:17 disk use is healthy,current value is 14% # 退出查看 & exit
例3
内存使用率检查,发送邮件告警
[root@hadoop04 shell]# vim mem_usage_mail.sh #!/usr/bin/bash # 获取内存使用情况 mem_used=`free -m | grep Mem | awk '{print $3}'` mem_total=`free -m | grep Mem | awk '{print $2}'` mem_percent=$((100*mem_used/mem_total)) warn_file=/tmp/mem_warn.txt health_file=/tmp/mem_health.txt # 删除告警文件,以免对告警造成误导 rm -rf ${warn_file} # 判断内存使用情况 if [ ${mem_percent} -ge 80 ];then echo "[warning] `date +%F %H:%M:%S` memory: ${mem_percent}%" > ${warn_file} else echo "[healthy] `date +%F %H:%M:%S` memory: ${mem_percent}%" >> ${health_file} fi # 告警文件存在,就发邮件告警;发送完成后,删除告警文件 if [ -f ${warn_file} ];then mail -s "mem warn ..." alice < ${warn_file} rm -rf ${warn_file} fi
字符串比较
建议
:字符串使用双引号引起来
判断字符串是否相等
# username变量不存在,直接判断会出现语法错误 [root@hadoop04 shell]# [ $username = "root" ] -bash: [: =: unary operator expected [root@hadoop04 shell]# echo $? 2 [root@hadoop04 shell]# [ $username != "root" ];echo $? -bash: [: !=: unary operator expected 2 # 使用双引号,可以规避上面的语法错误 [root@hadoop04 shell]# [ "$username" = "root" ] [root@hadoop04 shell]# echo $? 1 [root@hadoop04 shell]# [ "$username" != "root" ];echo $? 0
判断字符串长度
小结
:变量为空 或 未定义,长度都为 0
# 定义一个var,不赋值即变量值的长度为0 [root@hadoop04 shell]# var= [root@hadoop04 shell]# echo ${#var} 0 #判断长度是否等于0时,存在问题,都可以判断为True [root@hadoop04 shell]# [ -z $var ];echo $? 0 [root@hadoop04 shell]# [ -n $var ];echo $? 0 # 使用双引号,可以规避上面的判断问题 [root@hadoop04 shell]# [ -z "$var" ];echo $? 0 [root@hadoop04 shell]# [ -n "$var" ];echo $? 1
应用案例
输入数量和用户前缀,创建用户的脚本
[root@hadoop04 shell]# vim useradd01.sh #!/usr/bin/bash ########################################## # useradd # # v1.0 by ElegantSmile 8/12/2019 # ########################################## read -p "please input number: " num read -p "please input prefix: " prefix for i in `seq ${num}` do username=${prefix}${i} useradd ${username} echo "123" | passwd -stdin ${username} &> /dev/null #filename=${prefix}${i} #touch ${filename} if [ $? -eq 0 ];then echo "${username} is created" fi done
升级版:增加对数量和用户前缀的判断,非法输入将直接退出脚本
[root@hadoop04 shell]# vim useradd02.sh #!/usr/bin/bash ########################################## # useradd # # v1.0 by ElegantSmile 8/12/2019 # ########################################## read -p "please input number: " num # 判断输入的num是否为数字 if [[ ! "${num}" =~ ^[0-9]+$ ]];then echo "error number!" exit fi read -p "please input prefix: " prefix # 判断是否输入prefix if [ -z "${prefix}" ];then echo "error prefix" exit fi for i in `seq ${num}` do username=${prefix}${i} useradd ${username} echo "123" | passwd -stdin ${username} &> /dev/null #filename=${prefix}${i} #touch ${filename} if [ $? -eq 0 ];then echo "${username} is created" fi done
再升级版:增加循环判断,非法输入将进入循环,直到输入正确的变量
[root@hadoop04 shell]# vim useradd03.sh #!/usr/bin/bash ########################################## # useradd # # v1.0 by ElegantSmile 8/12/2019 # ########################################## read -p "please input number: " num while true do # 判断输入的num是否为数字 if [[ "${num}" =~ ^[0-9]+$ ]];then break else echo "error number!" read -p "please input number: " num fi done read -p "please input prefix: " prefix while true do # 判断是否输入prefix if [ -n "${prefix}" ];then break else echo "error prefix!" read -p "please input prefix: " prefix fi done for i in `seq ${num}` do username=${prefix}${i} useradd ${username} echo "123" | passwd -stdin ${username} &> /dev/null #filename=${prefix}${i} #touch ${filename} if [ $? -eq 0 ];then echo "${username} is created" fi done
特殊符号复习
()
子shell中执行命令
[root@hadoop04 ~]# (date) Sun Dec 8 21:07:18 CST 2019
(())
C语言风格的数值比较
[root@hadoop04 ~]# ((1<2));echo $? 0
$()
命令替换,相当于反引号``
[root@hadoop04 shell]# touch `date +%F`.txt [root@hadoop04 shell]# ll -rw-r--r--. 1 root root 0 Dec 8 21:09 2019-12-08.txt # [root@hadoop04 shell]# touch $(date +%F).txt [root@hadoop04 shell]# ll -rw-r--r--. 1 root root 0 Dec 8 21:09 2019-12-08.txt
$(())
整数运算
[root@hadoop04 shell]# echo $((1+2)) 3
{}
集合
[root@hadoop04 shell]# touch file{1..10}.txt
${}
变量引用
[]
条件测试:文件测试,数值比较,字符串比较
[[]]
除了[]支持的一般条件测试以外,还支持正则表达式 =~
测试条件之间的逻辑关系在[]和[[]]有所不同
逻辑与
[ EXPRESSION1 -a EXPRESSION2 ] [[ EXPRESSION1 && EXPRESSION2 ]]
逻辑或
[ EXPRESSION1 -o EXPRESSION2 ] [[ EXPRESSION1 || EXPRESSION2 ]]
$[]
整数运算
执行脚本
# ./01.sh 需要执行权限 在子 shell 中执行 # bash 01.sh 不需要执行权限 在子 shell 中执行 # . 01.sh 不需要执行权限 在当前 shell 中执行 # source 01.sh 不需要执行权限 在当前 shell 中执行
提示:通常修改系统配置文件中如 /etc/profile 的 PATH 等变量后,使之在当前 shell 中生效
调试脚本
# sh -n xxx.sh 仅调试 syntax error # sh -vx xxx.sh 以调试的方式执行,查询整个执行过程
command
此为补充内容,command
可以检查一个对象是否是一个命令
command -v 对象
示例
[root@hadoop04 ~]# command -v /etc/hosts; echo $? 1 [root@hadoop04 ~]# command -v test; echo $? test 0 [root@hadoop04 ~]# command -v vim; echo $? /usr/bin/vim 0
测试脚本
[root@hadoop04 shell_case]# vim command_test.sh #!/usr/bin/bash read -p "Please input a command: " com if command -v "${com}" &> /dev/null;then # :即true,此处表示不做任何操作 : else echo "you need to yum install ${com}." fi # 测试脚本 # 输入test命令,脚本无任何显示,表示test是一个命令 [root@hadoop04 shell_case]# bash command_test.sh Please input a command: test # 输入/home/test,脚本提示需要安装该命令,表示test不是一个命令或者系统上未装 [root@hadoop04 shell_case]# bash command_test.sh Please input a command: /home/test you need to yum install /home/test.
来源:https://www.cnblogs.com/ElegantSmile/p/12014969.html