03Shell条件测试

℡╲_俬逩灬. 提交于 2019-12-10 10:45:33

条件测试

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.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!