shell-if判断语句
- 1.什么是if
- 2.为什么要用if
- 3.if基础语法
- 4.基于文件进行判断
- 5.基于整数比对
- 6.基于字符比对
- 7.基于正则比对
1.什么是if
if其实就是模仿人类的判断来进行的,要么真、要么假、就这两种结果。
2.为什么要用if
判断
3.if基础语法
单条件
if [ 如果你有房 ];then
那就嫁
fi
双条件
if [ 如果你有房 ];then #真
嫁
else #假
不嫁
fi
多条件
if [ 如果你有房 ];then
嫁
elif [ 如果你有车 ];then
嫁
elif [ 人很帅 ];then
嫁
......
else
再见
fi
案例1:
单分支,判断当前用户是不是root1,如果不是那么返回“ERROR”
可以通过环境变量$USER判断当前用户
echo $USER
#!/bin/bash
if [ $USER != "root1" ];then
echo "ERROR!"
fi
案例2:
双分支,判断当前登录用户是管理员还是普通用户,如果是管理员输出”hey admin“ 如果是普通用户输出”hey guest“
#如何辨别是管理员还是普通用户:环境变量 $UID 只要为0 就一定是管理员 否则都是普通用户
#!/bin/bash
if [ $UID -eq 0 ];then #$UID等于0,输出hey admin
echo "hey admin"
else #否则输出hey guest
echo "hey guest"
fi
案例3:
多分支,根据输入一个用户名称,判断输入的用户是否存在当前系统,如不存在则再次判断用户是否在/home下拥有家目录,如果都没有则提示不存在
#!/bin/bash
read -p "输入一个用户名:" user
user1=$(cat /etc/passwd|grep $user|wc -l)
if [ $user1 -ne 0 ];then
echo "$user 存在当前系统"
elif [ -e /home/$user ];then
echo "$user 在/home下拥有家目录"
else
echo "$user 不存在"
fi
4.基于文件进行判断
用来备份时,需要使用
if [ -f /etc/hosts ];then
文件存在怎么样
else
文件不存在怎么样
fi
案例1:
备份/etc/hosts文件至/backup/system/filename-2024-03-11,如果该目录不存在则自动创建。
1.判断目录是否存在,不存在则创建
2.cp备份,并重命名
#!/bin/bash
dest=/backup/system
if [ ! -d $dest ];then #如果目录不存在,就创建目录
mkdir -p $dest
fi
cp -rp /etc/hosts $dest/filename-$(date +%F) #执行备份操作
案例2:
继需求1,判断备份的文件是否存在,如果不存在则提示”No such file or directory“,然后退出
#!/bin/bash
dest=/backup/system
#1.判断备份的目录是否存在
if [ ! -d $dest ];then
mkdir -p $dest
fi
#2.提示用户需要备份原文件
read -p "输入你要备份的文件" src
#3.判断用户输入的源文件是否存在,如果不存在则报错,退出
if [ ! -f $src ];then
echo "$src No such file or directory"
exit
fi
#4.如果文件存在,则直接执行拷贝操作
cp -rp $src $dest/
案例3:
继需求1、2,判断备份的文件是否为空,如果为空则提示"This is file empty",然后退出。
#!/bin/bash
dest=/backup/system
if [ ! -d $dest ];then
mkdir -p $dest
fi
read -p "输入你要备份的文件" src
if [ ! -f $src ];then
echo "$src No such file or directory"
exit
fi
if [ ! -s $src ];then #4.判断文件是否为空,如果为空,则报错。
echo "This is file empty"
exit
fi
cp -rp $src $dest/
5.基于整数比对
用来判断服务是否正常、选择时
案例1:
用户执行脚本,sh status.sh nginx,则检查nginx服务的运行状态。(仅支持传递一个参数)
#1.如何判断nginx的状态
0 启动
3 未启动
#!/bin/bash
#1.判断执行脚本的身份是不是root用户
if [ $USER != "root" ];then
echo "请使用root用户执行该脚本"
exit
fi
#2.判断用户传递的参数,$#总共传递的参数个数是
if [ $# -ne 1 ];then
echo "请按照正确格式执行脚本: sh $0 [ nginx | vsftpd | httpd ] "
exit
fi
systemctl status $1 &> /dev/null #将原本输出到屏幕的信息重定向到 /dev/null
if [ $? -eq 0 ];then #判断上一条命令执行返回的结果
echo "$1 是启动状态"
else
echo "$1 未启动状态"
fi
案例2:
查看磁盘/当前使用状态,如果使用率超过30%则报警
#!/bin/bash
diskuse=$(df -h|awk '/\/$/{print $(NF-1)}') #获取到磁盘使用的百分比
if [ ${diskuse%\%} -ge 30 ];then #先将结果替换成整数,然后再与预先设定的值进行比较
echo "warning!磁盘使用率为 $diskuse"
else
echo "磁盘正常,当前使用率为 $diskuse"
fi
6.基于字符比对
用来判断是不是root用户执行,如果不是则拒绝执行脚本
不等于
#!/bin/bash
#1.判断执行脚本的身份是不是root用户
if [ $USER != "root" ];then
echo "请使用root用户执行该脚本"
exit
fi
等于
#!/bin/bash
if [ $USER == "root" ];then
echo "hey admin"
else
echo "hey guest"
fi
#!/bin/bash
read -p "请输入一个字符:" action
if [ -z $action ];then #字符串长度为0,则执行输出指令
echo "请输入有效的字符"
exit
fi
7.基于正则比对
用来判断用户输入的是不是全整数,输入的是不是全小写、或大写
if [[ $USER =~ ^r ]];then #如果USER变量的结果匹配 r开头则表达式成立
fi
案例1:
通过正则的方式控制用户输入的必须是纯数字。
#!/bin/bash
read -p "输入一个纯数字" num
#判断$num的结果是否匹配以数字开头,数字出现一次或多次,以数字结尾,不匹配就输出报错信息
if[[! $num =~ ^[0-9]+$]];then
echo "输入的必需是纯数字"
exit
案例2:
编写一个创建用户的脚本。
1.提示用户输入要创建用户的前缀,必须是英文。
2.提示用户输入后缀,必须是数字。
3.如果前缀和后缀都没有问题,则进行用户创建。
思路梳理:
id 用户名 ,如果执行返回的结果是0,说明用户已存在
#!/bin/bash
read -p "输入用户名前缀:" qz
if [[ ! $qz =~ ^[a-z]+$ ]];then
echo "前缀必须是英文"
exit
fi
read -p "输入用户名后缀:" hz
if [[ ! $hz =~ ^[0-9]+$ ]];then
echo "后缀必须是数字"
exit
fi
username=$qz$hz
id $username &> /dev/null #将原本输出到屏幕的错误信息与普通信息全都重定向到/dev/null(所有输出都丢弃)
if [ $? -eq 0 ];then
echo "${username} 已存在"
else
useradd $username
echo "${username} 创建成功"
fi
案例3:
创建qwe01至qwe12 这12个用户
#!/bin/bash
source /etc/init.d/functions
#在shell脚本中,你可以通过source命令或者.操作符来调用/etc/init.d/functions库文件中定义的函数
read -p "输入用户名前缀:" qz
if [[ ! $qz =~ ^[a-z]+$ ]];then
echo "前缀必须是英文"
exit
fi
read -p "输入用户名后缀:" hz
if [[ ! $hz =~ ^[0-9]+$ ]];then
echo "后缀必须是数字"
exit
fi
#将用户输入的数字,进行序列化一下
for i in $(seq -w $hz ) #1至$hz按序列输出$hz的结果
do
username=$qz$i
id $username &> /dev/null
if [ $? -eq 0 ];then
action "${username} 已存在" /bin/false #action 也是输出的意思,类似于echo,但功能略有不同/bin/true显示效果为OK,/bin/false显示效果为FAILED
else
useradd $username
action "${username} 创建成功" /bin/true
fi
done
执行结果:
案例4:
判断nginx服务是否正常启动
#!/bin/bash
ngx_status=$(pidof nginx|wc -l)
if [ $ngx_status -eq 1 ];then
echo "nginx 服务正常"
else
echo "nginx 服务异常"
fi
案例5:
写一个Nginx安装脚本,加入判断,当上一步执行成功在执行下一步,否则退出脚本,
安装完成后,判断一下是否没有问题,配置完后,判断一下是否没有问题,最后启动,启动后检查没有问题,则提示用户可以访问了。
这里使用了编译的方式安装的nginx
思路梳理:
大概分为:安装、配置、启动 这三个大步骤
日常手动编译安装的基本步骤:
下载 nginx软件wget http://nginx.org/download/nginx-1.23.1.tar.gz
解压 tar xf nginx-1.23.1.tar.gz
进入nginx目录 cd /nginx-1.23.1
配置安装选项 ./configure --prefix=/etc/nginx
编译和安装 make && make install
启动nginx
/usr/sbin/nginx -t
/usr/sbin/nginx
查看结果
通过脚本实现这些步骤
#!/bin/bash
source /etc/init.d/functions #引入库方便后续使用
#判断/opt下是否存在源码包 ,-e 如果文件或目录存在则为真
if [ -e /opt/nginx-1.23.1.tar.gz ];then #如果/opt下存在源码包,就跳过下载的步骤
echo "源码包已存在无需再次下载"
else #如果/opt下不存在源码包,就下载到指定的路径/opt下
wget -P /opt http://nginx.org/download/nginx-1.23.1.tar.gz &>/dev/null
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示下载成功
action "nginx 下载" /bin/true
else
action "nginx 下载" /bin/false
exit
fi
fi
#安装nginx的依赖
yum install -y gcc pcre pcre-devel zlib zlib-devel &>/dev/null
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示安装nginx的依赖成功
action "nginx 依赖安装" /bin/true
else
action "nginx 依赖安装" /bin/false
exit
fi
#进入/opt下,解压包并进入解压后的nginx路径
cd /opt
tar xf nginx-1.23.1.tar.gz && cd nginx-1.23.1
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示解压成功进入路径成功
action "nginx 源码包解压" /bin/true
echo "Makefile生成中..."
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx #配置安装选项
#--prefix=<path> -- 安装路径,如果没有指定,默认为/usr/local/nginx。
#--sbin-path=<path> -- nginx可执行命令的文件,如果没有指定,默认为<prefix>/sbin/nginx
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示配置安装选项成功
action "nginx Makefile生成" /bin/true
make && make install #编译和安装
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示编译和安装成功
action "nginx 编译和安装" /bin/true
else
action "nginx 编译和安装" /bin/false
exit
fi
else
action "nginx Makefile生成" /bin/false
exit
fi
else
action "nginx 源码包解压" /bin/false
exit
fi
#nginx systemd服务单元文件创建
cat >/etc/systemd/system/nginx.service<< EOF
[Unit]
Description=The NGINX HTTP and reverse proxy server #描述Service的信息
After=network.target #表示nginx.service在network.target 单元之后启动
[Service]
Type=forking
PIDFile=/etc/nginx/logs/nginx.pid #配置安装选项过程中会显示,一般是/安装路径/logs/nginx.pid
ExecStartPre=/usr/sbin/nginx -t #定义启动服务前执行的指令
ExecStart=/usr/sbin/nginx #定义启动程序执行的指令
ExecReload=/usr/sbin/nginx -s reload #重启服务时执行的命令
ExecStop=/usr/sbin/nginx -s quite #停止服务时执行的命令
PrivateTmp=true
#PrivateTmp,使用Systemd这个进程作为启动进程的linux系统,其子进程都会有PrivateTmp这么一个属性,用于设置是否使用私有的tmp目录,/tmp目录一般是所有用户和所有service都共享的,把各个service的tmp目录隔开的话,可以保证一定的安全性。
[Install]
#配置开机自启动
WantedBy=multi-user.target
EOF
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示服务文件创建成功
systemctl daemon-reload #重新加载systemd管理配置,然后就可以使用systemctl控制nginx了,不然还需要使用绝对路径来控制nginx服务的启动停止。
action "nginx systemd服务单元文件创建" /bin/true
echo "可使用 systemctl [ start | stop | status | reload | enable ] nginx 控制nginx服务!"
else
action "nginx systemd服务单元文件创建" /bin/false
echo "请手动配置 '/etc/systemd/system/nginx.service' 文件"
exit
fi
#配置文件语法验证,验证不报错的话,就可以启动nginx了
#/usr/sbin/nginx -t 以绝对路径的方式,验证配置文件语法是否正确
nginx -t #直接验证配置文件语法是否正确
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示语法正确
action "nginx 配置文件验证" /bin/true
systemctl start nginx #以systemctl命令控制nginx启动
#/usr/sbin/nginx 以绝对路径控制nginx启动
if [ $? -eq 0 ];then #上一个命令执行的返回结果没有问题就表示成功启动
action "nginx 启动" /bin/true
else
action "nginx 启动" /bin/false
exit
fi
else
action "nginx 配置文件验证" /bin/false
echo "存在语法错误"
exit
fi
#查看返回头部信息中的HTTP状态码,进行判断,等于200的话就是请求成功,成功返回了请求的资源
status_code=$(curl -I -s http://localhost |awk 'NR==1{print $2}') #-I 仅输出HTTP请求头 -s 静默模式,不输出额外的信息
if [ $status_code -eq 200 ];then
echo "index页面访问正常"
else
echo "index页面访问异常 服务返回状态码:$status_code "
fi
执行效果:
大概就这样了,这里写的啰嗦了,还可以继续优化
案例6:
在每月13号,备份并压缩/etc目录的所有内容,存放到/opt/bak目录,
存放的形式为: 年-月-日_etc.tar.gz
思路梳理:
1.备份什么 /etc目录
2.备份到哪 /opt/bak (有没有这个目录,有待考究,没有的话还的创建这个目录)
3.备份时间 每月13号
#!/bin/bash
destdir=/opt/bak #备份到的目录
date=$(date +%F) #日期格式
day=$(date +%d) #输出日,这个月的哪一日
#判断要备份到的目录是否存在,不存在的话还的创建这个目录
if [ ! -d $destdir ];then
mkdir -p $destdir
fi
#判断今天是不是13号,是的话进行备份操作
if [ $day == 13 ];then
cd /
tar cfz ${destdir}/${date}_etc.tar.gz etc/ #tar cfz 压缩后文件名.tar.gz 打包的目录
fi
赋予可执行权限
chmod 777 /tmp/bak.sh
加入定时任务 crontab -e
查看定时任务 crontab -l
0 0 * * * /tmp/bak.sh #每天执行一次脚本