Shell 脚本编程:if 条件语句
if 条件语句概述
if 条件语句是 Linux Shell 脚本编程中最基础且使用频率最高的控制结构之一,其语义类似于自然语言中的“如果…那么…”。熟练掌握 if 语句的用法,是成为一名合格运维工程师的基本要求。
if 语句基础语法
1. 单分支结构
语法格式一:
if <条件表达式>then 指令
fi
语法格式二(推荐使用):
if <条件表达式>;then指令
fi
说明:第二种语法中的分号相当于命令换行,两种语法功能完全相同,第二种更简洁。
示例:目录不存在时创建目录
if [ ! -d /tmp/furongwang ];thenmkdir /tmp/furongwang # 如果/tmp/furongwang目录不存在,则创建该目录
fi
2. 双分支结构
语法格式:
if <条件表达式>;then指令集1
else指令集2
fi
示例:检查目录是否存在
if [ -d /tmp/furongwang ];thenecho "/tmp/furongwang is exist" # 目录存在时输出信息
elsemkdir /tmp/furongwang # 目录不存在时创建目录
fi
3. 多分支结构
语法格式:
if <条件表达式1>;then指令1
elif <条件表达式2>;then指令2
else指令3
fi
if 条件表达式类型
1. test 条件表达式
if test 表达式;then指令
fi
2. [ ] 条件表达式
if [ 字符串或算术表达式 ];then指令
fi
3. [[ ]] 条件表达式
if [[ 字符串或算术表达式 ]];then指令
fi
4. (( )) 条件表达式
if ((算术表达式));then指令
fi
5. 命令表达式
if 命令;then指令
fi
说明:以上表达式语法不同但功能一致,可根据个人习惯选择使用。
if 语句实践示例
示例1:检测并启动 sshd 服务
#!/bin/bash
systemctl is-active sshd &>/dev/null # 检查sshd服务状态
if [ $? -ne 0 ];then # 如果返回值不为0(服务未运行)echo "sshd is not running, I'll start sshd."systemctl start sshd # 启动sshd服务
fi
示例2:检测sshd服务并输出状态信息
#!/bin/bash
systemctl is-active sshd &>/dev/null
if [ $? -ne 0 ];thenecho "sshd is not running."echo -n "Starting sshd ... ..."systemctl start sshd && echo "DONE" # 启动成功输出DONE
elseecho "sshd is running" # 服务已运行时输出信息
fi
示例3:通过参数控制sshd服务
#!/bin/bash
if [ "$1" == "start" ];thensystemctl start sshd
elif [ "$1" == "stop" ];thensystemctl stop sshd
elif [ "$1" == "status" ];thensystemctl status sshd
elif [ "$1" == "restart" ];thensystemctl restart sshd
elseecho "Usage: $0 start|stop|status|restart" # 参数错误时提示用法
fi
示例4:三个整数排序
#!/bin/bash
a=10
b=20
c=30# 如果a小于b,交换值,此时a大b小
if [ $a -lt $b ];thennum=$b;b=$a;a=$num
fi# 比较后两个值大小并交换,此时c值最小
if [ $b -lt $c ];thennum=$c;c=$b;b=$num;
fi# 比较前两个值大小并交换,此时a值最大
if [ $a -lt $b ];thennum=$b;b=$a;a=$num;
fiecho "$a>$b>$c" # 输出排序结果:30>20>10
示例5:内存监控报警
#!/bin/bash
FreeMem=$(free -m | awk 'NR==2 { print $4}') # 获取可用内存大小
if [ $FreeMem -lt 100 ];then# 内存低于100M时发送邮件报警echo "Mem is lower than 100M" | mail -s "FreeMem is ${FreeMem}M" root@localhost
fi
计划任务配置:
*/3 * * * * /path/to/monitor_mem.sh
实际案例
1. 监控 MySQL 数据库服务
#!/bin/bash
if ss -lnt|grep -q ':3306';then # 检查3306端口是否监听echo "MySQL is Running."
elseecho "MySQL is Not Running."
fi
2. 监控 Web 服务器
#!/bin/bash
if wget --timeout=10 --tries=2 www.redhat.com &>/dev/null;thenecho "Apache is Running."
elseecho "Apache is Not Running."
fi
3. 比较两个整数大小
#!/bin/bash# 判断参数个数
if [ $# -ne 2 ];thenecho "USAGE: $0 numl num2"exit 1
fi# 判断参数是否为整数
expr $1 + 1 &>/dev/null
RETVAL1=$?
expr $2 + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -o $RETVAL2 -ne 0 ];thenecho "please provide two int number"exit 2
fi# 比较大小
if [ $1 -lt $2 ];thenecho "$1 < $2"
elif [ $1 -eq $2 ];thenecho "$1 = $2"
elseecho "$1 > $2"
fi
4. 判断字符串是否为数字
# 方法1:使用sed删除数字
[ -z "$(echo 123|sed 's/[0-9]//g')" ] && echo int || echo char# 方法2:使用变量替换
num=123
[ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo int || echo char# 方法3:使用expr判断
expr $num + 1 &>/dev/null
[ $? -eq 0 ] && echo int || echo char# 方法4:使用正则表达式
[[ $num =~ ^[0-9]+$ ]] && echo int || echo char
5. 监控 Memcached 服务
#!/bin/bash
systemctl is-active memcached.service &>/dev/null
RetVal=$?if [ $RetVal -ne 0 ];thenecho "Memcached is not running."
else# 删除缓存中的keyprintf "del key\r\n"|nc 127.0.0.1 11211 &>/dev/null# 添加新值printf "set key 0 0 10 \r\nfurongwang1234\r\n"|nc 127.0.0.1 11211 &>/dev/null# 查询新值McCount=$(printf "get key\r\n"|nc 127.0.0.1 11211|wc -l)[ $McCount -eq 1 ] && \echo "Memcached status is ok." || \echo "Memcached status is error."
fi
6. Rsync 服务启动脚本
#!/bin/bash
# 判断参数个数
if [ $# -ne 1 ];thenecho "Usage: $0 [ start | stop | restart | status ]"exit 1
fi# 根据参数1做出相应动作
if [ "$1" = "start" ];thenrsync --daemonsleep 2# 判断当前状态if ss -lnt|grep -q ':873';thenecho "rsyncd is started."exit 0fi
elif [ "$1" = "stop" ];thenpkill rsync &>/dev/nullsleep 2# 判断当前状态if ! ss -lnt|grep -q ':873';thenecho "rsyncd is stoped."exit 0fi
elif [ "$1" = "status" ];then# 判断当前状态if ! ss -lnt|grep -q ':873';thenecho "rsyncd is stoped."elseecho "rsyncd is started."fi
elif [ "$1" = "restart" ];thenpkill rsync &>/dev/nullretval_1=$?sleep 1rsync --daemonretval_2=$?sleep 1# 判断停止和启动状态if [ $retval_1 -eq 0 -a $retval_2 -eq 0 ];thenecho "rsyncd is restarted."exit 0fi
elseecho "Usage: $0 [ start | stop | restart | status ]"exit 1
fi
执行结果:
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd start
rsyncd is started.
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd status
rsyncd is started.
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd stop
rsyncd is stoped.
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd status
rsyncd is stoped.
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd restart
[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd status
rsyncd is started.[furongwang@shell ~]$ sudo bash /etc/init.d/rsyncd hello
Usage: /etc/init.d/rsyncd [ start | stop | restart | status ]
[furongwang@shell ~]$ echo $?
1