🤠1. IF判断基本概述
1.1 什么是if?
if就是模仿人类的判断来进行的,但它没有人类那么有情感,只有true和false这两种结果
1.2 为什么要使用if?
当我们在写程序的时候,是否经常需要对上一步的执行结果进行判断,那么判断就需要使用到if语句来实现。
if语句在我们程序中主要就是用来做判断的,不管大家以后学习什么语言,只要涉及到判断的部分,大家可以直接拿if来使用,不同语言之间的if只是语法不同,原理是相同的。
1.3 if的基础语法
1>单分支结构
单分支语法 单分支代码示例
if [ 如果你有房 ];then if [ $1 -eq $2 ];then
我就嫁给你 echo "ok"
fi fi
单分支实列:
判断当前用户是不是cry,如果不是cry那么放回"error"
if [ $USER != "cry" ];then
echo "error"
fi
2>双分支结构
双分支语法 双分支代码示例
if [ 如果你有房 ];then if [ $1 -eq $2 ];then
我就嫁给你 echo "ok"
else else
再见 echo "error"
fi fi
双分支实列1:
判断当前登陆用户是管理源还是普通用户,
如果是管理员输出“hey admin”
如果是普通用户输出“hey guest”
脚本内容
if [ $USER == "root" ];then
echo "hey admin"
else
echo "hey guest"
fi
执行结果
双分支实列2:(嵌套if语句)
通过脚本传入两个参数,进行整数关系比较。
脚本内容
if [ $1 -eq $2 ];then
echo "$1 = $2 "
else
if [ $1 -gt $2 ];then
echo " $1 > $2 "
else
echo "$1 < $2 "
fi
fi
执行结果
3>多分支结构
多分支语法
if [ 如果你有房 ];then
我就嫁给你
elif [ 如果你有车];then
我就嫁给你
elif [ 如果你有房];then
我就嫁给你
else
再见
fi
多分支实列:
通过脚本传入两个参数,进行整数关系比较。
脚本内容
if [ $1 -eq $2 ];then
echo " $1 = $2 "
elif [ $1 -gt $2 ];then
echo " $1 > $2 "
else
echo " $1 < $2 "
fi
执行结果
🤠2.IF基于文件比较
参数 | 说明 | 示例 |
---|---|---|
-e | 如果文件或目录存在且为真 | [-e file] |
-s | 如果文件存在且至少有一个字符则为真 | [ -s file] |
-d | 如果文件存在且为目录则为真 | [-d file] |
-f | 如果文件存在且为普通文件则为真 | [-f file] |
-r | 如果文件存在且为可读则为真 | [-r file] |
-w | 如果文件存在且可写则为真 | [-w file] |
-x | 如果文件存在可执行且为真 | [-x file] |
题目:备份文件至/backup/system/,如果该目录不存在自动创建
题目要求
1.传递的参数仅1个
2.传递的文件不能是空
3.传递的文件不可以不存在
4.拷贝的位置必须存在
脚本内容
#1.仅能传递一个参数
if [ $# -ne 1 ];then
echo "please filename path"
exit
fi
#2.判断被传递的文件或目录是否存在
if [ ! -e $1 ];then
echo "$1 $1 file is not found"
exit
fi
#3.判断被传递的文件内容是否为空
if [ ! -s $1 ];then
echo " $1 file is empty"
exit
fi
#4.判断传递备份的路径是否存在
if [ ! -d /backup/system ];then
mkdir -p /backup/system/
fi
cp -rp $1 /backup/system/
执行脚本结果
🤠3.IF基于整数比较
参数 | 说明 | 示例 |
---|---|---|
-eq | 等于则条件为真 | [ 1 -eq 10] |
-ne | 不等于则条件为真 | [ 1 -ne 10] |
-gt | 大于则条件为真 | [ 1 -gt 10] |
-lt | 小于则条件为真 | [ 1 -lt 10] |
-ge | 大于等于则条件为真 | [ 1 -ge 10] |
-le | 小于等于则条件为真 | [ 1 -le 10] |
题目1:用户执行脚本 是sh status.sh nginx 则检查nginx服务的运行状态(仅支持传递一个参数)
脚本分析
首先我们需要
echo $?
来知道服务每一种状态返回的整数
开启为0
关闭为3
没有安装这个服务为4
然后对 0 3 4 做整数比较
脚本内容
#1.仅支持传递一个参数
if [ $# -ne 1 ];then
echo "USAGE: $0 {nginx | httpd |vsftpd }"
exit
fi
#2.判断服务状态
systemctl status $1 &>/dev/null
result=$?
if [ $result -eq 4 ];then
echo "$1 这个服务没有安装..."
elif [ $result -eq 3 ];then
echo "$1 这个服务没有开启..."
elif [ $result -eq 0 ];then
echo "$1 这个服务已经开启..."
else
echo "$1 这个服务发生未知错误..."
fi
脚本执行结果
题目2:获取进程的详情,
首先判断当前服务是否在运行,
如果运行则输出他的进程详情,
否则提示进程没有详情。
脚本书写分析
我们用pidof 这个命令来探测服务进程
pidof nginx 如果服务正在运行会以行返回出一行进程号
我们先要把这个结果转化成整数,进行整数比对。
pidof nginx |wc -l
echo $?
1为服务启动有进程
0为服务没有启动没有进程
脚本内容
process_status_pid=$(pidof $1) # 获取所有的进程ID编号
result=$(pidof $1 | wc -l) # 获取进程ID编号,转换为整数模式 ( 1 表示进程启动了 0 表示进程没有启动)
# 基于获取的进程ID整数判断,如果为1,说明进程存活
if [ $result -eq 1 ];then
# get_master_process变量中存储的是该进程的父进程
get_master_process=$(echo $process_status_pid | awk '{print $NF}')
# 通过ps过滤父进程,将详情赋值给 ps_status变量
ps_status=$(ps -ef | grep ${get_master_process} | grep -v grep )
echo "$1 进程详情...."
echo "$ps_status"
else
echo "$1 暂未启动"
fi
🤠4.IF基于字符串比较
参数 | 说明 | 示例 | 额外解释 |
---|---|---|---|
== | 等于则条件为真 | [ "$a" == "$b" ] | |
!= | 不相等则条件为真 | [ "$a" != "$b" ] | |
-z | 字符串的长度为零则为真 | [ -z "$a" ] | 内容空则为真 |
-n | 字符串的长度不为空则为真 | [ -n "$a" ] | 有内容则为真 |
4.1语法示例
等于(==)
[root@cry shell-if]#cat if.sh
#!/bin/bash
if [ $USER == "root" ];then
echo "hey admin"
else
echo "hey guest"
fi
不等于(!=)
[root@cry shell-if]#cat if.sh
#!/bin/bash
if [ $USER != "root" ];then
echo "error!"
exit
fi
判断用户输入是否为空-z
[root@cry shell-if]#cat if.sh
#!/bin/bash
read -p "请输入一个字符:" action
if [ -z $action ];then
echo "请不要直接回车..."
exit
fi
🤠5.IF基于正则比较
单括号无法使用正则语法
我们必须使用双[]才可以正则匹配
[root@cry shell-if]# [[ "$USER" =~^r ]];echo $?
0
题目:批量创建用户:提示用户输入要创建名称,以及要创建的数量
1.用户名称,必须是全字母
2.创建的个数,必须是整数,不可以带字母
3.不可以输入空
脚本内容
read -p "请输入你要创建的用户:" user
#1.不可以为空
if [ -z $user ];then
echo "不可以输入空格..."
exit
fi
#2.用户名称必须是纯字母
if [[ ! $user =~ ^[a-z]+$ ]];then
echo "请输入纯字母"
exit
fi
################################################################
read -p "请输入你要创建的数量:" number
#1.必须是纯整数
if [[ ! $number =~ ^[0-9]+$ ]];then
echo "请输入纯整数"
exit
fi
################################################################
read -p "你要创建的用户名称是: $user , 你要创建的数量是: $number , 你确定要创建吗? [Y|N]" action
if [ $action == "Y" ];then
for i in $(seq -w ${number})
do
user_name=$user$i
useradd $user_name &>/dev/null
echo "$user_name 创建成功!!!"
done
fi
执行脚本结果
🤠6.IF练习题
需求1:判断一个机器是否存活,能ping通就算存活
脚本内容
if [ $# -ne 1 ];then
echo " USAGE: $0 { 10.0.0.1 |10.0.0.2} "
exit
fi
ping -c1 -W2 $1 &>/dev/null
if [ $? -eq 0 ];then
echo "IP: $1 通..."
else
echo "IP: $1 不通..."
脚本执行结果
需求2:监控内存小于500m和磁盘容量小于10g,则发邮件报警
脚本内容
free_ava=$(free -m|awk '/M/{print $NF}')
disk_ava=$( df -h |awk '/\/$/{print $4}')
if [ ${free_ava} -lt 500 -a ${disk_ava%G} -lt 10 ];then
echo "当前内存和磁盘空间不足"
echo "内存: ${free_ava}Mb"
echo "磁盘: ${disk_ava}"
else
echo "当前内存和磁盘空间正常"
echo "内存: ${free_ava}Mb"
echo "磁盘: ${disk_ava}"
fi
脚本执行结果
需求3:检测本机当前用户是否为管理员,如果是则使用yum安装vsftpd。如果不是,则提示你非管理员
脚本内容
if [ $UID -eq 0 ];then
yum -y install vsftpd &>/dev/null
if [ $? -eq 0 ];then
echo " vsftpd 安装成功!!!"
else
echo " vsftpd 安装失败!!!"
fi
else
echo " $USER不是管理员,请使用管理员身份 "
fi
脚本执行结果
需求4:根据相同的系统不同版本,配置不同的yum源
脚本内容
os_relase_version=$(awk '{print $(NF-1)}' /etc/redhat-release)
if [ ${os_relase_version%%.*} -eq 7 ];then
wget -O /etc/yum.repos.d/shell-epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
fi
if [ ${os_relase_version%%.*} -eq 6 ];then
wget -O /etc/yum.repos.d/shell-epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
fi
脚本执行结果
需求5:安装不同版本的php方式,使用echo输出即可,不用真的安装
脚本分析
1.需要有一个菜单页面,告诉我有那些php的版本
2.根据用户的选择,执行对应的版本安装
cat <<EOF
#####################
1) Install php5.5
2) Install php5.6
3) Install php7.1
4) Install php7.2
>#####################
脚本内容
cat <<EOF
###################
1) Install php5.5
2) Install php5.6
3) Install php7.1
4) Install php7.2
###################
EOF
read -p "请根据编号选择你要按照的php版本[ 1 | 2 | 3 | 4 |]:" action
if [ -z $action ];then
echo "请不要输入空"
exit
fi
if [ $action -eq 1 ];then
echo "Install php5.5"
elif [ $action -eq 2 ];then
echo "Install php5.6"
elif [ $action -eq 3 ];then
echo "Install php7.1"
elif [ $action -eq 4 ];then
echo "Install php7.2"
fi
执行脚本结果
需求6:多条件判断年龄
- 如果姑娘小于18岁,打印”未成年"
- 如果姑娘大于18岁小于25岁,打印”表白“
- 如果姑娘大于25岁小于42岁,打印“阿姨好”
- 如果姑娘大于45岁,打印“奶奶好”
脚本分析
1.提示 ”请输入姑娘的年龄“
2.判断思路
低于18 ——》未成年
大于等于18并且小于等于25——》表白
大于25并且小于等于45——》阿姨好
大于45——》奶奶好
脚本内容
read -p "请输入姑娘的年龄:" action
#1.不能输入为空
if [ -z $action ];then
echo "不能输入为空"
exit
fi
#2.控制整数再两位数
if [[ ! $action =~ ^[0-9]{2}$ ]];then
echo "年龄没有这么大的!!!"
exit
fi
#3.年龄判断
if [ $action -lt 18 ];then
echo "这位姑娘是未成年"
elif [ $action -ge 18 -a $action -le 25 ];then
echo "我要对姑娘表白"
elif [ $action -gt 25 -a $action -lt 45 ];then
echo "回老家,别折腾"
elif [ $action -gt 45 ];then
echo "奶奶你好!!!"
fi
执行脚本结果
需求7:提示用户输入身高,如果身高达到180以上全票,120一下免票,其余不能进。
脚本分析
大于等于180——》全票
大于等于120 小于180——》不让进
小于120——》免票
脚本内容
read -p "请输入您的身高:" action
if [ -z $action ];then
echo "禁止输入空"
exit
fi
if [[ ! $action =~ ^[0-9]{3}$ ]];then
echo "请输入正确身高!!!"
exit
fi
if [ $action -gt 180 ];then
echo "您的身高必须买门票"
elif [ $action -ge 120 -a $action -lt 180 ];then
echo "您不准进!!!"
elif [ $action -lt 120 ];then
echo "您的身高可以免票"
fi
~
执行脚本结果
需求8:使用root用户清空/var/log/messages日志,并每次执行保留最近100行
脚本内容
#1.加锁
if [ -f /tmp/lock ];then
echo "$0 脚本正在运行...."
exit
fi
touch /tmp/lock
#2.确定身份
if [ $UID -ne 0 ];then
echo "$USER 用户不是管理员,请切换管理员用户身份..."
exit
fi
#追加
tail -n100 ${log_file} > ${log_file}.bak
#清空
> ${log_file}
echo "正在清理中============================="
sleep 3
if [ -s ${log_file} ];then
echo "清空 ${log_file} 失败..."
else
cat ${log_file}.bak >> ${log_file}
echo " clean ${log_file} is done..."
fi
#3.解锁
rm -rf /tmp/lock
执行脚本结果
需求9:判断网站服务(httpd和nginx)是否正常启动,可以通过pidof,netstat,curl多种方式
脚本分析
1.判断进程是否存在
存在
2.判断端口是否存在
存在
3.判断网站是否正常
存在
httpd服务与网络一起正常
不存在
不存在 httpd进程。端口存在,网络异常
httpd进程存活,但是端口未检测到
不存在
httpd进程不存活
脚本内容
read -p "请输入你要检测的web服务:" action
if [ -z $action ];then
echo "请不要输入空,可以选择输入{httpd |nginx}"
exit
fi
pidof=$(pidof $action|wc -l)
#1.判断进程是否存在
if [ $pidof -eq 1 ];then
#进程存在
#2.判断端口是否存在
netstat=$(netstat -lntup|grep $action|wc -l)
if [ $netstat -ne 0 ];then
#端口存在
#3.判断网站是否正常
curl=$(curl -s -w %{http_code} localhost -o /dev/null)
#网站正常
if [ $curl -eq 200 ];then
echo -e "\e[42m 进程正常,端口正常,网站正常。网站的状态码是 $curl \e[0m"
else
echo -e "\e[41m 进程正常,端口正常,网站异常。网站的状态码是 $curl \e[0m"
#网站不正常
fi
#端口不存在
else
echo "$action 进程存活,但是端口未检测到 "
fi
#进程不存在
else
echo "$action 进程不存活!!!"
fi
执行脚本结果
需求10:写一个nginx编译安装脚本
ngx_opt=/opt
ngx_version=nginx-1.19.5
ngx_install=/usr/local
#0.加锁
if [ -f /tmp/lock ];then
echo "$0 脚本正在运行...."
exit
fi
touch /tmp/lock
#1.解决依赖
yum install gcc redhat-rpm-config libxslt-devel gd-devel perl-ExtUtils-Embed geoip-devel gperftools-devel pcre-devel openssl-devel lsof -y
#2.官方下载nginx
if [ ! -f ${ngx_opt}/${ngx_version}.tar.gz ];then
wget -O ${ngx_opt}/${ngx_version}.tar.gz http://nginx.org/download/${ngx_version}.tar.gz
fi
#3.解压软件包
if [ ! -d ${ngx_opt}/${ngx_version} ];then
cd ${ngx_opt} && \
tar xf ${ngx_version}.tar.gz
fi
#4.进行编译操作
if [ ! -d ${ngx_install}/${ngx_version} ];then
cd ${ngx_opt}/${ngx_version} && \
./configure --prefix=${ngx_install}/${ngx_version} && \
make && \
make install && \
ln -s ${ngx_install}/${ngx_version} ${ngx_install}/nginx
if [ ! -e ${ngx_install}/nginx ];then
echo "Nginx编译失败..."
exit
fi
else
echo "Nginx已经安装了,无法重复安装"
fi
#5.启动服务 { 80端口是否被占用 }
port_check=$(lsof -i :80 | wc -l)
if [ ${port_check} -eq 0 ];then
${ngx_install}/nginx/sbin/nginx -t &>/dev/null
if [ $? -eq 0 ];then
${ngx_install}/nginx/sbin/nginx
else
echo "nginx配置文件异常,无法启动..."
exit
fi
else
#kill占用端口的进程
kill $(lsof -i :80 | sed 1d | awk '{print $2}' | xargs)
port_check=$(lsof -i :80 | wc -l)
if [ ${port_check} -eq 0 ];then
${ngx_install}/nginx/sbin/nginx -t &>/dev/null
if [ $? -eq 0 ];then
${ngx_install}/nginx/sbin/nginx
else
echo "nginx配置文件异常,无法启动..."
exit
fi
fi
fi
#6.测试
website_code=$(curl -o /dev/null -s -w %{http_code} "localhost")
If_eth0=$(ifconfig eth0 | awk 'NR==2 {print $2}')
if [ ${website_code} -eq 200 ];then
echo "Nginx 访问成功,请通过 http://${If_eth0} 访问获取页面.."
else
echo "nginx 访问失败,请检查,状态码为: ${website_code}"
fi
#7.解锁
rm -rf /tmp/lock
执行脚本结果
需求11:在每月第一天备份并压缩/etc目录的所有内容,存放到、opt/bak目录,存放的形式2019_04_10_etc.tar.gz
脚本分析
1.定时任务crontab
2.判断备份目录是否存在
如果不存在就创建
3.打包/etc/ 目录,并且以时间戳命名
脚本内容
backup_path=/opt/bak
date=$(date +%F)
#1.判断备份目录是否存在
if [ ! -d ${backup_path} ];then
mkdir -p ${backup_path}
fi
#2.进行打包操作
cd / && \
tar zcf ${backup_path}/${date}_etc.tar.gz etc
#3.判断打包文件是否存在备份目录下
if [ -f ${backup_path}/${date}_etc.tar.gz ];then
echo "$(date +%F-%T): Backup...成功!!!" >> /tmp/backup.log
else
echo "$(date +%F-%T): Backup...失败!!!" >> /tmp/backup.log
fi
执行脚本结果
需求12:输入三个数并进行升序排序
脚本内容
if [ $# -ne 3 ];then
echo "必须传递三个参数"
exit
fi
echo "$1 $2 $3" | xargs -n1 | sort -n
执行脚本结果
需求13:提示用户输入年份后判断该年是否为闰年(能整除4,并且不能被100整除则为闰年)
脚本分析
1.判断平年
2.判断闰年
2.1 能被4整除并且不能被100整除
或者
2.2 能被400整除
脚本内容
read -p "请输入一个年份:" action
if [ $[ $action % 4 ] -eq 0 -a $[ $action %100 ] -ne 0 -o $[ $action %400 ] -eq 0 ];then
echo "$action is 闰年"
else
echo "$action is 平年"
fi
执行脚本结果
那如果我们想定义一个文件,文件的内容是1945年到2020年,我们就需要用到循环
seq 1945 2020 >year.txt
while read Action
do
if [ $[ $Action % 4 ] -eq 0 -a $[ $Action % 100] -ne 0 -o $[ $Action % 400 ] -eq 0 ];then
echo "$Action 是闰年"
fi
done < year.txt
需求14:根据用户输入密码位数,生成随机密码(包含数字,大小写字母,特殊符号)
脚本分析
根据用户输入密码位数,生成随机密码(包含数字、大小写字母、特殊符号)
分析:
1.提示用户输入要创建名称: oldboy User
2.提示用户输入要创建的个数: 10 Number
3.提示用户输入密码的位数: 12 Count
yum install -y expect 安装mkpasswd创建随机数命令,注意,输入7以下命令不会生成密码
是:
1.进入循环: 保证循环10次:
随机密码: Pass=$(mkpasswd -l $Count)
定义好完整用户名称: Username=$User+ 循环的变量 $i
创建用户 useradd $Usernmae
设定密码 echo "$Pass" | passwd --stdin $Username
否:
退出完事
脚本内容
read -p "用户输入要创建名称:" User
read -p "提示用户输入要创建的个数:" Number
read -p "提示用户输入密码的位数:" Count
read -p "创建的用户名称是 $User , 创建个数是 01 ~ $Number , 生成的随机密码位数是: $Count 确定要创建 [ Y | N] " Action
if [ $Action == "Y" ];then
for i in $(seq -w ${Number})
do
Pass=$(mkpasswd -l $Count)
# 定义完整的用户名称
Username=$User$i
# 判断用户是否存在
id $Username &>/dev/null
if [ $? -ne 0 ];then
useradd $Username && \
echo "${Pass}" | passwd --stdin $Username &>/dev/null
echo "${Username}:${Pass} Is Create..."
# 将创建的结果输出到文件中...
echo "${Username}:${Pass} Is Create..." >> user_pass.txt
fi
done
else
echo "Bye..."
exit
fi