当我们在写程序的时候,经常需要对上一步的执行结果进行判断,那么判断就需要使用if语句来实现。
if语句在我们程序中主要就是用来做判断的。
一、if语法
1.1 单分支if
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
# 上述语法可以用一行代码代替
[ 条件信息 ] && 执行命令
监视磁盘使用情况超过80%报警
[root@localhost ~]# cat disk_monitor.sh
#!/usr/bin/env bash
disk_use=$(df -P |grep '/$' |awk '{print $5}' |awk -F% '{print $1}')
if [ $disk_use -gt 89 ];then
echo "warning:Not enough hard disk space"
fi
[root@localhost ~]# sh disk_monitor.sh
warning:Not enough hard disk space
注意:if 测试中还可以执行命令 根据命令的返回值做判断
[root@localhost ~]# if cd /etc;then echo yes;fi
yes
1.2 if 双分支
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
else
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
# 上述语法可以用一行代码代替
[ 条件信息 ] && xxx || yyy
1.2.1 模拟登录
[root@localhost ~]# cat login.sh
#!/bin/bash
User="bertwu"
Passwd="123"
read -p "请输入用户名:" user
read -p "请输入密码:" passwd
if [ $User == "$user" -a $Passwd == "$passwd" ];then
echo "登录成功" && exit
else
echo "用户名或密码错误"
fi
1.3 多分支if
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
elif 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
elif 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
...
else
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
1.3.1 猜年龄:
[root@manager scripts]# cat age.sh
Age=78
while true
do
read -p "请输入年龄:" age
if [[ ! $age =~ ^[0-9]+$ ]];then # 非数字提示用户重新输入
echo "please input a digit"
continue
fi
if (($age > $Age));then
echo "too big"
continue
elif (($age < $Age));then
echo " too small"
continue
else
echo "you are greate, get it"
break
fi
done
1.3.2 成绩查询
#!/bin/bash
read -p "your score>>> " score
[[ ! $score =~ ^[0-9]+$ ]] && echo "请输入数字" && exit
if [ $score -ge 90 ];then
echo "优秀"
elif [ $score -ge 70 ];then
echo "良好"
elif [ $score -ge 60 ];then
echo "一般"
else
echo "较差"
fi
1.4 判断是否是数字
[root@manager scripts]# cat isdigit.sh
read -p "请输入一个数值: " num
while :
do
if [[ $num =~ ^[0-9]+$ ]];then
break
else
read -p "不是数字,请重新输入数值: " num
fi
done
echo "你输入的数字是: $num"
1.5 传入文件,判断文件类型
[root@manager scripts]# cat test_file.sh
#!/bin/bash
if [ -L $1 ];then
echo "$1 is a link"
elif [ -d $1 ];then
echo "$1 is a directory"
elif [ -b $1 ];then
echo "$1 is a block"
elif [ -f $1 ];then
echo "$1 is a file"
else
echo "unknow"
fi
[root@manager scripts]# sh test_file.sh /bin
/bin is a link
[root@manager scripts]# sh test_file.sh /etc
/etc is a directory
1.6 判断用户是否存在
[root@manager scripts]# cat check_user.sh
#/bin/bash
id $1 &>/dev/null
if (($?==0));then
echo "$1 存在"
else
echo "$1 不存在"
fi
[root@manager scripts]# sh check_user.sh root
root 存在
[root@manager scripts]# sh check_user.sh tom
tom 存在
[root@manager scripts]# sh check_user.sh xx
xx 不存在
1.7 检测httpd软件是否安装,没有的话则安装
[root@manager scripts]# cat check_httpd.sh
#!/bin/bash
rpm -qa | grep httpd &>/dev/null
if [ $? -eq 0 ];then
echo "httpd已经安装"
else
yum install httpd -y &>/dev/null
fi
1.8 判断80端口的状态,未开启则重启
[root@manager scripts]# cat check_port.sh
#!/bin/bash
netstat -lntp | egrep ":80 " &>/dev/null
if (($?==0));then
echo "80端口已启动"
else
echo "80端口down,正在重启"
systemctl restart httpd &>/dev/null
sleep 3
netstat -lntp | egrep ":80 " &>/dev/null
if (($?==0));then
echo "80端口启动成功"
else
echo "启动失败"
fi
fi
1.9 编写监控脚本,并发邮件
- 根分区剩余空间小于10%
- 或者内存的可用空间小于30%
- 向用户bertwu发送告警邮件,邮件的内容包含使用率相关信息
[root@manager scripts]# cat monitor.sh
#!bin/bash
disk_used=$(df | grep '/$' | awk -F '%' '{print $1}' | awk '{print $NF}') # 根分区磁盘使用率
Men_used=$(free -m | grep "Mem" | awk '{print $3*100/$2}') # 内存使用率
if (( $disk_used > 90 ));then
echo "磁盘已经使用了90%,超出警戒线" | mail -s "磁盘报警" bertwu@qq.com
fi
if [ $(echo "$Men_used > 70" | bc) -eq 1 ];then
echo "内存已经使用了 70%,超出警戒线" | mail -s "内存报警" bertwu@qq.com
fi
mailx配置
[root@localhost ~]# yum install mailx -y
[root@localhost ~]# cat /etc/mail.rc
set from=xxx@qq.com
set smtp=smtps://smtp.qq.com:465
set smtp-auth-user=xxx@qq.com
set smtp-auth-password="xxxxxxxxxx"
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb/
名词解释:
set from:设置发件人
set smtp:设置外部STMP服务器
set smtp-auth-user:设置STMP用户名(一般为完整邮箱地址)
set smtp-auth-password:设置SMTP密码,需要登录xxx@qq.com在设置->账户->开启POP3/SMTP服务->获取密码
1.10 备份脚本
需求1:备份文件至/backup/system/filename_2021-8-29,如果该目录不存在则自动创建。
1.源文件,让用户手动输入;
2.目标位置:/backup/system/ 判断, 判断该目录,是否存在,如果不存在则创建;
[root@manager scripts]# cat backup.sh
dir=/backup/system
read -p "请输入源文件路径:" src
if [ ! -d $src ] && [ ! -f $src ];then
echo "文件不存在"
exit
fi
if [ ! -s $src ];then
echo "文件不能为空"
exit
fi
if [ ! -d $dir ];then
mkdir $dir -p
fi
filename=$(echo ${
src##*/})
cp -rpv $src $dir/${
filename}_$(date +%F)
1.11 为执行文件加锁
当一个脚本在运行时候,原则上不允许其他人对脚本的操作,这样就要对脚本加锁
[root@manager scripts]# cat lock.sh
#!/bin/bash
if [ -f /tmp/run.lock ];then
echo "该脚本正在运行。。。"
exit
fi
# 加锁
touch /tmp/run.lock
# 业务代码
sleep 30
# 运行结束,解锁
if [ -f /tmp/run.lock ];then
rm -rf /tmp/run.lock
fi
1.12 查看服务运行状态
[root@manager scripts]# cat status.sh
#!/bin/bash
if [ ! $# -eq 1 ];then
echo "USAGE: $0 { nginx | mysql | httpd| haproxy | zabbix-agent}"
exit
fi
systemctl status $1 &>/dev/null # 查看状态 0正常已经启动,3未启动 4.未安装
flag=$?
if [ $flag -eq 0 ];then
echo "$1服务正常"
elif [ $flag -eq 3 ];then
echo "$1 服务未启动"
elif [ $flag -eq 4 ];then
echo "$1 未安装"
read -p "是否需要安装$1服务:[yes|no]" action
if [ ${
action:=no} == "yes" ];then
yum install $1 -y
else
exit
fi
fi
1.13获取进程详情
1.首先要传递参数,1个,服务的名称;
2.判断:是否存在该进程,如果不存在,则警告,然后退出脚本;
2.获取进程的pid相关的信息; ps aux|grep $1
3.还需要该服务的active (running)
4.值需要提取运行的用户:pid,STAT,command命令
[root@manager scripts]# cat process.sh
#bin/bash
read -p "请输入服务名称:" name
systemctl status $name &>/dev/null
flag=$?
if [ $flag -eq 4 ];then
read -p "服务未安装,是否安装[yes|no default:yes]" action
if [ ${
action:=yes} == "yes" ];then
yum install $name -y
if [ $? -eq 0 ];then
echo "$name安装成功"
else
echo "$name 安装失败"
exit
fi
else
echo "获取信息失败!"
exit
fi
systemctl start $name
if [ $? -eq 0 ];then
echo "$name 启动成功"
else
echo "启动失败,未获取任何信息"
fi
else [ $flag -eq 3 ]
systemctl start $name
fi
# 重新判断服务状态
systemctl status $name &>/dev/null
flag=$?
if [ $flag -ne 0 ];then
echo "该服务没救了"
exit
else
# 获取进程的详细信息
# 业务逻辑
service_runtime=$(systemctl status $name | grep Active | awk '{print $2,$3}')
echo "当前 $name 进程的状态是:"
echo "$name : $service_runtime"
echo "****************************************************"
echo "当前 $name 进程的详情是: "
ps aux|grep $name | grep -v grep | grep -v "$$" | awk 'BEGIN {printf "%-15s%-15s%-20s\n","进程的用户","进程的PID","进程的命令"} {printf "%-20s%-20d%-20s\n",$1,$2,$NF}' > /tmp/${
name}.txt
echo "***************************************************"
cat /tmp/${
name}.txt
rm -rf /tmp/${
name}.txt
fi
1.14 三个数据排序
1.控制只能输入三个参数;
2.将行,转为列的显示方式;
3.sort排序;
[root@manager scripts]# cat sort.sh
#/bin/bash
if [ $# -ne 3 ];then
echo "请输入三个数字"
exit
fi
if [[ $1 =~ ^[0-9]+$ ]] && [[ $2 =~ ^[0-9]+$ ]] && [[ $3 =~ ^[0-9]+$ ]];then
echo "$1 $2 $3" | xargs -n1 | sort
else
echo "必须是纯数字"
exit
fi
1.15 判断用户输入是否为空
[root@manager scripts]# cat input.sh
#!/bin/bash
read -p "请输入内容:" action
if [ -z $action ];then
echo "输入非法"
exit
fi
echo "你输入的内容是:$action"
1.16 检查selinux是否为disabled
[root@manager scripts]# cat selinux.sh
#!/bin/bash
status=$(grep "^SELINUX=" /etc/selinux/config | awk -F "=" '{print $2}')
if [ ! $status == "disabled" ];then
sed -i '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
echo "已经关闭selinux"
else
echo "selinux已经处于关闭状态"
fi
1.17 创建用户
需求:编写一个创建用户的脚本。
1.提示用户输入要创建用户的前缀,必须是英文。
2.提示用户输入后缀,必须是数字。 010203
3.如果前缀和后缀都没有问题,则进行用户创建。
4.并且密码是随机的;
[root@manager scripts]# cat adduser.sh
#!/bin/bash
read -p "请输入用户名,必须以字母开头,数字结尾:" username
if [[ $username =~ ^[a-z]+ ]] && [[ $username =~ [0-9]+$ ]];then
id $username &>/dev/null
if (( $?==0 ));then
echo "用户已经存在"
exit
else
useradd $username
password=$(echo $RANDOM | md5sum | cut -b 1-6)
echo $password | passwd --stdin $username
fi
echo $username:$password >> /opt/pass.txt
else
echo "用户名输入非法"
fi
1.18 备份
需求:在每月第一天备份并压缩/etc目录的所有内容,存放到/opt/bak目录,存放的形式
2021_10_10_etc.tar.gz,脚本名称为fileback,存放在/root的家目录下。
[root@localhost scripts]# cat fileback.sh
dir=/opt/bak
lock_file=/tmp/back.lock
log_file=/var/log/$0.log
log_format=$(date +%F_%T):$(hostname):$0
# 判断运行身份
if [ ! $USER == "root" ];then
echo "权限不够,请用root身份运行"
echo "$log_formart" >> $log_file
exit
else
echo "$log_format $USER 开始运行备份脚本" >> $log_file
fi
if [ -f $lock_file ];then
echo "该脚本正则运行,请稍后。。。"
exit
fi
# 加锁
touch /tmp/back.lock
# 判断备份目录是否存在
if [ ! -d $dir ];then
mkdir $dir
fi
# tar 打包 /etc
echo "$log_formart 开始进行打包" >> $log_file
cd / && tar czf $dir/$(date +%F)_etc.tar.gz etc
if [ -f $dir/$(date +%F)_etc.tar.gz ];then
echo "$log_format $USER用户 打包/etc目录成功" >> $log_file
else
echo "$log_format $USER用户 打包/etc/目录失败" >> $log_file
fi
# 解锁
rm -rf $lock_file
二、case
case 语句和 if 多分支判断语句类似,主要用来做多条件判断;只不过 case 在 Shell 脚本中比 if 多分支条件判断更方便。
在生产环境中,我们会根据”一个问题“ 做多种预案,然后根据用户选择来加载不同的预案。比如服务的启停脚本,我们首先要写好启动、停止、重启的预案,然后根据用户选择来加载不同的预案。
2.1 case语法
case 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后命令序列
esac
[root@localhost scripts]# cat case1.sh
#!/bin/bash
cat <<EOF
****************
** 1. backup **
** 2. copy **
** 3. quit **
****************
EOF
read -p "Input a choose: " OP
case $OP in
1|backup)
echo "BACKUP......"
;;
2|copy)
echo "COPY....."
;;
3|quit)
exit
;;
*)
echo error!
esac
示例1
[root@localhost scripts]# cat user.sh
read -p "input username:" -t 10 username
if [ -z $username ];then
username="default"
fi
case $username in
root)
echo "管理员用户"
;;
bertwu)
echo "普通用户"
;;
default)
echo "默认用户"
;;
*)
echo "无权限"
esac
2.2 编写nginx启停脚本
[root@manager scripts]# cat nginx_stat.sh
#!/bin/bash
. /etc/init.d/functions
args=$1
fun(){
[ $? -eq 0 ] && action "Nginx $args is ok" /bin/true || action "Nginx $args is filed" /bin/false
}
case $1 in
start)
netstat -lntp | grep nginx &>/dev/null
if [ $? -eq 0 ]
then
echo "Nginx is runing..."
else
/usr/sbin/nginx
fun
fi
;;
stop)
/usr/sbin/nginx -s stop
fun
;;
reload)
/usr/sbin/nginx -s reload
fun
;;
restart)
netstat -lntp | grep nginx &>/dev/null
if [ $? -ne 0 ]
then
/usr/sbin/nginx
[ $? -eq 0 ] && echo "Nginx start is ok" || echo "Nginx start is failed"
else
/usr/sbin/nginx -s stop
[ $? -eq 0 ] && echo "Nginx stop is ok" || echo "Nginx stop is failed"
sleep 2
/usr/sbin/nginx
fun
fi
;;
status)
netstat -lntp | grep nginx &>/dev/null
if [ $? -eq 0 ]
then
echo "Nginx is runing ..."
else
echo "Nginx is not runing ..."
fi
;;
*)
echo "Usage: $0 {start|stop|status|restart|reload}"
exit 2
esac
2.3 编写rsync启停脚本
[root@rsync ~]# cat rsyncd.sh
#!/bin/bash
. /etc/init.d/functions
fun(){
[ $? -eq 0 ] && action "Rsyncd $args is ok" /bin/true || action "Rsync $args is failed" /bin/false
}
start_rsync(){
args=start
netstat -lntp | grep rsync &>/dev/null
if [ $? -eq 0 ];then
action "rsync is running....." /bin/true
else
/usr/bin/rsync --daemon
fun
fi
}
stop_rsync(){
args=stop
netstat -lntp | grep rsync &>/dev/null
if [ $? -ne 0 ];then
action "rsync is not running....."
else
pid=$(ps aux | grep "[r]sync --daemon" | awk '{print $2}') # rsync进程号
kill -9 $pid
fun
fi
}
case $1 in
start)
start_rsync
;;
stop)
stop_rsync
;;
restart)
stop_rsync
start_rsync
;;
status)
systemctl status rsyncd | grep Active
;;
*)
echo "USAGE $0 [start | stop | restart | status ]"
esac