03Shell条件测试
条件测试
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.
03Shell条件测试的更多相关文章
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- shell条件测试test
shell条件测试可以通过以下两种方式: test 参数 测试内容 [ 参数 测试内容 ] 一.测试文件类型: test -e 文件名 (测试文件是否存在) [ - ...
- Linux Shell 03 条件测试
条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...
- bash Shell条件测试
3种测试命令: test EXPRESSION [ EXPRESSION ] [[ EXPRESSION ]] 注意:EXPRESSION前后必须有空白字符 bash的测试类型 数值测试: -eq: ...
- 关于read的例子和条件测试
1.关于read比较两个的大小 #!/bin/sh read -t -p "please input two num:" a b if [ $a -gt $b ]; then ec ...
- shell脚本进阶之条件测试与条件语句
接着上篇博客,今天整理一下关于条件测试和条件语句方面的知识. shell脚本进阶之条件测试 在编写shell脚本时,经常需要对一些条件进行判断,可以使用测试命令test辅助完成测试过程.t ...
- 【转】shell学习笔记(四)——条件测试
1 test 条件检测 当我要检测系统上面某些文件或者是相关的属性时,利用 test 这个命令来工作真是好用得不得了, 举例来说,我要检查 /home/oracle/zy是否存在时,使用: test ...
- 【转】shell学习笔记(三)——引用变量、内部变量、条件测试、字符串比较、整数比较等
1.env显示当前的环境变量 2.PS1='[\u@\h \w \A] \$' 可以设置bash的命令与提示符. 3.echo $$ 显示当前bash的PID号 4.echo $?显示上一条指令的回传 ...
- Shell编程-条件测试 | 基础篇
什么是Shell Shell是一个命令解释器,它会解释并执行命令行提示符下输入的命令.除此之外,Shell还有另一个功能,如果要执行多条命令,它可以将这组命令存放在一个文件中,然后可以像执行Linux ...
随机推荐
- python接口自动化12-pytest前后置与fixture
前言 我们都知道在自动化测试中都会用到前后置,pytest 相比 unittest 无论是前后置还是插件等都灵活了许多,还能自己用 fixture 来定义.(甩 unttest 半条街?) 首先了解一 ...
- H5纯前端生成Excel表格
H5纯前端生成Excel表格方法如下: <!DOCTYPE html> <html> <head> <title></title> < ...
- Mysql - 存储过程 - 定时删表
在工业监控里面, 需要对每天的数据, 进行记录, 时间长了之后, 数据库很容易撑爆. 这时候, 如果允许, 可以对之前的数据进行一次清除, 只记录几个月内的数据. delimiter $ DROP P ...
- TCP协议 - 面向连接
一.TCP特性概览 1.面向连接 TCP是基于连接进行数据交互,通信双方在进行数据交互之前需要建立连接,该连接也只能用在双方之间进行交互.这点不像UDP中的组播和广播,可以在同一组中多个主机交互数据. ...
- java高并发系列 - 第3天:有关并行的两个重要定律
有关为什么要使用并行程序的问题前面已经进行了简单的探讨.总的来说,最重要的应该是处于两个目的. 第一,为了获得更好的性能: 第二,由于业务模型的需要,确实需要多个执行实体. 在这里,我将更加关注第一种 ...
- Delphi - 创建SuperDll 持续更新
Delphi SuperDll 作为一名5年的Delpher,一直认为Delphi是桌面应用的王者,我相信其他的Delpher也这么认为. 但是,慢慢的我发现普通方式的Delphi开发会造成代码的严重 ...
- python基础(34):线程(二)
1. python线程 1.1 全局解释器锁GIL Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行.虽然 Py ...
- 数据库-用户管理与pymysql
mysql用户管理 !这是dba的活儿!,但是万一公司没有dba? mysql用户指的是什么? 我们每一次在操作前都需要指定账号和密码,这个账号就是mysql的用户; 为什么要管理? 一个公司不可能只 ...
- git终端提交代码
- Gatech OMSCS的申请和学习之奥妙
https://zhuanlan.zhihu.com/p/54680585 我写东西一向希望能给大家带来正能量,提供有价值的信息,不辱没母校的厚德价值观. 我是传统没落工科毕业后开发软件,但是一直没下 ...