内容目录

if判断语句

什么是if

  • if就是模仿人类的判断来进行的,但它没有人类那么有情感,只有TrueFalse这两种结果

为何要使用if

  • 当我们在写程序的时候,经常需要对上一步的执行结果进行判断,那么判断就需要使用if语句来实现
  • if语句在我们程序中主要就是用来做判断的
  • 不管大家以后学习什么语言,以后只要涉及到判断的部分,大家就可以直接拿if来使用
  • 不同的语言之间的if只是语法不同,原理是相同的

if的基础语法

单分支结构
# 单分支代码示例
if [ $1 -eq $2 ];then
    echo "ok"
fi
双分支结构
# 双分支代码示例
if [ $1 -eq $2 ];then
    echo "ok!"
  else
    echo "error!"
fi
多分支结构
# 多分枝代码示例
if [ 如果你有房 ];then
    我就嫁给你
  elif[ 你有车 ];then
    我就嫁给你
  elif[ 你有钱 ];then
    我就嫁给你
  else
    再见
fi

if分支场景

单分支脚本案例
  • 需求:判断当前用户是不是root,如果不是那么返回error
cat if_1.sh
#!/usr/bin/bash

if [ $USER != 'root' ];then
    echo "error"
    exit 1
fi
双分支脚本案例
  • 需求:判断当前登录用户是管理员还是普通用户
    • 如果是管理员输出hey admin
    • 如果是普通用户输出hey guest
cat if_2.sh
#!/usr/bin/bash

if [ $USER == 'root' ];then
    echo "hey admin"
  else
    echo "hey guest"
fi
多分支脚本案例
  • 需求:通过脚本传入两个整数参数,进行整数关系比较
  • 请使用双分支和多分支两种方式实现
cat if_3.sh
#!/usr/bin/bash

# 双分支,嵌套if方式实现
if [ $1 -eq $2 ];then
    echo "$1 = $2"
else
    if [ $1 -gt $2 ];then
        echo "$1 > $2"
    else
        echo "$1 < $2"
    fi
fi
  • 多分支结构实现
cat if_4.sh
#!/usr/bin/bash

if [ $1 -eq $2 ];then
    echo "$1 = $2"
  elif [ $1 -gt $2 ];then
    echo "$1 > $2"
  else
    echo "$1 < $2"
fi

if基于文件比较

  • if语句中的文件比较
    • -e:如果文件或目录存在则为真
    • -s:如果文件存在且至少有一个字符则为真
    • -d:如果文件存在且为目录则为真
    • -f:如果文件存在且为普通文件则为真
    • -r:如果文件存在且为可读则为真
    • -w:如果文件存在且为可写则为真
    • -x:如果文件存在且为可执行则为真
备份脚本案例-1
  • 需求:备份文件至/backup/system/filename-2024-5-5,如果该目录不存在则自动创建
  • 源文件,让用户手动输入
  • 目标位置:/backup/system/判断,判断该目录是否存在,如果不存在则创建
cat if_5.sh
#!/usr/bin/bash

Dest_Dir=/backup/system/
Date=$(date +%F)

read -p "请输入你要备份的文件:" Src_File
read -p "是否将$Src_File文件备份为$Dest_Dir$Src_File-$Date? [ yes | no ]" action

if [ ! -d $Dest_Dir ];then
        mkdir -p $Dest_Dir
fi

if [ $action == yes ];then
        cp -rpv $Src_File $Dest_Dir$Src_File-$Date
fi
备份脚本案例-2
  • 需求:继上,判断备份的文件是否存在
    • 如果备份文件存在则继续
    • 如果备份文件不存在则提示No Such file,然后退出
cat if_5.sh
#!/usr/bin/bash

Dest_Dir=/backup/system/
Date=$(date +%F)

read -p "请输入你要备份的文件:" Src_File

# 判断用户输入的路径是否存在,是否是一个文件
if [ ! -f ${Src_File} ];then
    echo "No Such File ${Src_File} !"
    exit
fi

read -p "是否将${Src_file} 文件备份到 ${Dest_Dir}/filename-${Date} [ yes | no ]" Action

if [ ! -d $Dest_Dir ];then
        mkdir -p $Dest_Dir
fi

if [ $action == yes ];then
        cp -rpv $Src_File $Dest_Dir$Src_File-$Date
fi
备份脚本案例-3
  • 需求3:继上需求,判断备份的文件是否为空
    • 如果备份文件不为空则继续
    • 如果备份文件为空,则提示This is empty file,然后退出
cat if_5.sh
#!/usr/bin/bash

Dest_Dir=/backup/system/
Date=$(date +%F)

read -p "请输入你要备份的文件:" Src_File

# 判断用户输入的路径是否存在,是否是一个文件
if [ ! -f ${Src_File} ];then
    echo "No Such File ${Src_File} !"
    exit
fi

# 判断文件为空,则报错退出脚本
if [ ! -s ${Src_File} ];then
    echo "This ${Src_File} is empty file!"
    exit
fi

read -p "是否将${Src_file} 文件备份到 ${Dest_Dir}/filename-${Date} [ yes | no ]" Action

if [ ! -d $Dest_Dir ];then
        mkdir -p $Dest_Dir
fi

if [ $action == yes ];then
        cp -rpv $Src_File $Dest_Dir$Src_File-$Date
fi
为执行脚本加锁
cat lock.sh
#!/usr/bin/bash

# 判断是否存在锁
if [ -f /tmp/test.lock ];then
   echo "该脚本正在运行,请稍后..."
   exit
fi

# 加锁
touch /tmp/test.lock

### 业务逻辑
sleep 20

# 解锁
if [ -f /tmp/test.lock ];then
    rm -f /tmp/test.lock
fi

if基于整数比较

  • if语句中的整数比较 [ 整数1 操作符 整数2 ] equal to;great than;less than
    • -eq:等于则条件为真,示例:[ 1 -eq 10 ]
    • -ne:不等于则条件为真,示例:[ 1 -ne 10 ]
    • -gt:大于则条件为真,示例:[ 1 -gt 10 ]
    • -lt:小于则条件为真,示例:[ 1 -lt 10 ]
    • -ge:大于等于则条件为真,示例:[ 1 -ge 10 ]
    • -le:小于等于则条件为真,示例:[ 1 -le 10 ]
检测服务状态脚本
  • 需求:用户执行脚本sh status.sh nginx则检查nginx服务的运行状态(仅支持传递一个参数)
cat status.sh
#!/usr/bin/bash

if [ $# -ne 1 ];then
    echo "USAGE:$0 [ nginx | zabbix-agent2 | chronyd | mariadb | httpd | vsftpd | Service_Name... ]"
    exit
fi

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 服务已经启动..."
fi
获取linux版本
  • 需求:获取linux版本
cat release.sh
#!/usr/bin/bash

system_status=$(cat /etc/redhat-release  | awk '{print $(NF-1)}')

if [ ${system_status%%.*} -eq 7 ];then
        echo "linux 7"
elif [ ${system_status%%.*} -eq 6 ];then
        echo "linux 6"
fi
获取进程详情脚本
  • 需求:获取进程的详情
    • 1.首先要传递参数,1个,服务的名称
    • 2.判断:是否存在该进程,如果不存在,则警告,然后退出脚本
    • 3.获取进程的pid相关的信息;
cat process.sh
#!/usr/bin/bash

if [ $# -ne 1 ];then
        echo "USAGE: $0 [ nginx | zabbix-agent2 | sshd | php-fpm | ... ]"
        exit
fi

get_service=$(pidof $1 | wc -l)

if [ $get_service -ge 1 ];then
        ps -ef | grep -v grep | egrep "$( pidof $1 | sed 's# #|#g')" > /tmp/$1_status.txt
        echo "打印当前 $1 进程的详情..."
        sleep 1; echo ""

        cat /tmp/$1_status.txt && rm -f /tmp/$1_status.txt
else
        echo "$1 服务没有进程详情..."
fi
数字排序脚本
  • 需求:输入三个数并进行升序排序
    • 1.控制只能输入三个参数
    • 2.将行,转为列的显示方式
    • 3.sort排序
cat sort.sh
#!/usr/bin/bash

if [ $# -ne 3 ];then
        echo "请传递三个参数"
        exit
else
        echo "$1 $2 $3" | xargs -n1 | sort -n
fi

if基于字符比较

  • if语句中的字符串比较[ 字符1 操作符 字符2 ]
    • ==:等于则条件为真,示例`[ $a == $b ]
    • !=:不相等则条件为真,示例[ $a != $b ]
    • -z:字符串的长度为零则为真(内容空则为真),示例[ -z $a ]
    • -n:字符串的长度不为空则为真(有内容则为真),示例[ -n $a ]
检查执行身份是否为root
  • 需求:判断用户是否为root超级管理员
    • 如果是则提示hey admin
    • 如果不是则提示hey guest
cat root.sh
#!/usr/bin/bash

if [ $USER == root ];then
        echo "hey admin"
else
        ehco "hey guest"
fi

# 不等于写法!=
cat root-2.sh
#!/usr/bin/bash

if [ $USER != root ];then
    echo "ERROR"
    exit
fi
判断用户输入是否为空脚本
cat zero.sh
#!/usr/bin/bash

read -p "请输入一个字符:" action

if [ -z $action ];then
        echo "请不要直接回车..."
        exit
else
        echo "你输入的是 $action "
fi
检查selinux是否为disabled

检查是否为disabled状态
是:则输出该状态已经是disabled,不做修改;
否:则修改状态为disabled,并返回一段提示,说selinux已经修改为disabled

cat selinux.sh
#!/usr/bin/bash

selinux_file=/etc/selinux/config
selinux_status=$(grep "^SELINUX=" $selinux_file | awk -F '=' '{print $NF}')

if [ $selinux_status != disabled ];then
        sed -i '/^SELINUX=/c SELINUX=disabled' $selinux_file
        echo "selinux已修改为disabled状态"
else
        echo "selinux已经是disabled状态,无需修改"
fi

if基于正则比较

  • if语句中的正则比较 [[ 变量 =~ 正则匹配的内容 ]]
    • [[ $USER =~ ^r ]]:判断用户是否已r开头
    • [[ $num =~ ^[0-9]+$ ]]:判断用户输入的是否为全数字
  • 注意:单中括号使用正则语法会报错
控制用户输入必须为整数脚本
  • 需求:通过正则方式控制用户输入的必须是数字
cat number.sh
#!/usr/bin/bash

read -p "请输入一个数值:" num
if [[ ! $num =~ ^[0-9]+$ ]];then
        echo "你输入的不是数字,程序退出!!!"
        exit
fi
echo "你输入的数字是:$num"
遍历单词筛选其中关键字脚本
  • 需求:使用for循环打印一堆单词,然后仅输出以r开头的单词
cat r.sh
#!/usr/bin/bash

for var in ab ac rx bx rvv vt root
do
        if [[ $var =~ ^r ]];then
                echo $var
        fi
done
批量创建用户脚本
  • 需求:编写一个创建用户的脚本
    • 1.提示用户输入要创建用户的前缀,必须是英文
    • 2.提示用户输入后缀,必须是数字
    • 3.如果前缀和后缀都没有问题,则进行用户创建
    • 4.并且密码是随机的
cat useradd_batch.sh
#!/usr/bin/bash
. /etc/init.d/functions

read -p "请输入用户的前缀:" qz
# 判断用户输入的前缀
if [[ ! $qz =~ ^[a-z]+$  ]];then
        echo "你输入的不是纯英文..."
        exit 1
fi

read -p "请输入用户的后缀:" hz
if [[ ! $hz =~ ^[0-9]+$ ]];then
        echo "你输入的不是纯数字..."
        exit 2
fi

#开始拼接用户输入的前缀+后缀=user_name变量
user_name=$qz$hz
id $user_name &> /dev/null
if [ $? -eq 0 ];then
        echo " $user_name 用户已存在"
        exit 3
else
        useradd $user_name
        action "$user_name 用户创建成功" /bin/true
fi

if判断相关脚本案例

备份脚本场景

  • 需求:在每月第一天备份并压缩/etc目录的所有内容,存放到/opt/bak目录,存放的形式2024_06_16_etc.tar.gz,脚本名称为fileback,存放在/root的家目录下
    • 1.借助定时任务
    • 2.判断/opt/bak是否存在
    • 3.tar czf /opt/bak/datetime_etc.tar.gz etc
cat fileback.sh
#!/usr/bin/bash

Date=$(date +%F)
Dir=/opt/bak
Lock_File=/tmp/back.lock
Log_File=/var/log/${0}.log
Log_Format="$(date +%F_%T) $(hostname) $0:"

# 1.判断操作的用户身份
if [ ! $USER == "root" ];then
        Log_Format="$(date +%F_%T) $(hostname) $0:"
        echo "$Log_Format 请使用root身份运行..." >> ${Log_File}
        exit
else
        Log_Format="$(date +%F_%T) $(hostname) $0:"
        echo "$Log_Format root开始执行备份脚本--->" >> ${Log_File}
fi

# 2.加锁
if [ -f $Lock_File ];then
        echo "该脚本 $0 正在执行备份操作--->"
        exit
fi

# 第一次备份时,没有锁,所以需要添加
touch $Lock_File

# 3.判断备份的目录是否存在
if [ ! -d $Dir ];then
        mkdir -p $Dir
fi

# 4.执行tar打包
Log_Format="$(date +%F_%T) $(hostname) $0:"
echo "$Log_Format root开始执行tar命令打包--->" >> ${Log_File}
sleep 2
cd / && tar czf ${Dir}/${Date}_etc.tar.gz etc
if [ -f ${Dir}/${Date}_etc.tar.gz ];then
        Log_Format="$(date +%F_%T) $(hostname) $0:"
        echo "$Log_Format 备份文件 ${Dir}/${Date}_etc.tar.gz 成功--->" >> ${Log_File}
else
        Log_Format="$(date +%F_%T) $(hostname) $0:"
        echo "$Log_Format 备份文件 ${Dir}/${Date}_etc.tar.gz 失败--->" >> ${Log_File}
fi

# 5.程序执行成功后记得解锁
rm -f $Lock_File

创建随机密码脚本

  • 需求:根据用户输入密码位数,生成随机密码(包含数字、大小写字母、特殊符号)
    • 1.怎么生成随机数,mkpasswd -l 8
    • 2.控制输入的长度,最少8位,最多20位
cat mkpasswd.sh
#!/usr/bin/bash

read -p "请输入你想生成的随机数密码位数:" Action

if [[ ! $Action =~ ^[0-9]+$ ]];then
        echo "请输入数字..."
        exit
fi

if [ $Action -ge 8 -a $Action -le 20 ];then
        mkpasswd -l $Action
else
        echo "密码长度应为8-20位!"
fi

case判断语句

什么是case

  • case语句和if多分支判断语句类似,主要用来做多条件判断
  • 只不过caseshell脚本中比if多分支条件判断更方便

case使用场景

  • 在生产环境中,我们会根据一个问题做多种预案,然后根据用户选择来加载不同的预案
  • 比如服务的启停脚本,我们首先要写好启动、停止、重启的预案,然后根据用户选择来加载不同的预案

case基础语法

  • case基础语法
case $1 in start
条件 1)
    执行代码块1
    ;;
条件 2)
    执行代码块2
    ;;
条件 3)
    执行代码块3
    ;;
*)
    无匹配后命令
esac
  • case示例:
cat case.sh
#!/usr/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-编写rsync启停脚本

先在配置文件配置记录pid

cat /etc/rsyncd.conf
pid file = /var/run/rsyncd.pid
cat rsync.sh
#!/usr/bin/bash
. /etc/init.d/functions

Rsync_Pid_File=/var/run/rsyncd.pid

start_rsync(){
        # 判断pid是否存在,如果存在说明服务已经启动过了
        if [ -f $Rsync_Pid_File ];then
                action "Rsync正在运行中,不用重复启动..." /bin/false
        else
                /usr/bin/rsync --daemon
                Rsync_Status=$(netstat -lntp | grep 873 | grep -w "tcp" | wc -l)

                if [ $Rsync_Status -eq 1 ];then
                        action "Rsync 启动成功" /bin/true
                else
                        action "Rsync 启动失败" /bin/false
                fi
        fi
}

stop_rsync(){
        # 判断是否存活
        if [ -f $Rsync_Pid_File ];then
                # 停止
                kill $(cat ${Rsync_Pid_File})
                sleep 0.5
                Rsync_Status=$(netstat -lntp | grep 873 | grep -w "tcp" | wc -l)

                if [ $Rsync_Status -eq 0 ];then
                        action "Rsync 停止成功" /bin/true
                else
                        action "Rsync 停止失败" /bin/false
                fi
        else
                # 已经是停止状态
                action "Rsync 已经是停止状态" /bin/false
        fi
}

case $1 in
        start)
                start_rsync
        ;;

        stop)
                stop_rsync
        ;;

        restart)
                if [ -f $Rsync_Pid_File ];then
                        stop_rsync
                        start_rsync
                else
                        start_rsync
                fi
        ;;

        status)
                if [ -f $Rsync_Pid_File ];then
                        rsync_pid=$(cat ${Rsync_Pid_File})
                        echo ""
                        echo "***********************Rsync Status********************"
                        rsync_process_message=$(ps aux|grep ${rsync_pid} | grep -v grep)
                        echo "${rsync_process_message}"
                        echo "*******************************************************"
                else
                        action "Rsync 暂未启动..." /bin/false
                fi
        ;;

        *)
                echo "Usage $0 [ start | status | restart | stop ]"
                exit
esac
场景2-编写nginx启停脚本
cat nginx.sh
#!/usr/bin/bash
. /etc/init.d/functions

ngx_pid=/var/run/nginx.pid
ngx_tmp=/tmp/ngx.status
case $1 in
        start)
                # 判断服务是否存活
                if [ ! -f $ngx_pid ];then
                        nginx -t &> /${ngx_tmp}
                        if [ $? -ne 0 ];then
                                ngx_file=$(cat /tmp/ngx.status | awk '/emerg/' | awk '{print $NF}' | awk -F ":" '{print $1}')
                                ngx_line=$(cat /tmp/ngx.status | awk '/emerg/' | awk '{print $NF}' | awk -F ":" '{print $2}')

                                read -p "Nginx的 ${ngx_file} 的第 ${ngx_line} 行出现了错误,是否需要进入编辑 [ y | n ]:" Action

                                if [ ${Action:=y} == "y" ];then
                                        vim ${ngx_file} +${ngx_line}
                                else
                                        exit
                                fi
                        else
                                # 启动
                                /usr/sbin/nginx
                                # 查看进程
                                ngx_process_id=$(cat ${ngx_pid})
                                ngx_process_message=$(ps aux | grep ${ngx_process_id} | grep -v grep | wc -l)
                                if [ $ngx_process_message -ge 1 ];then
                                        action "Nginx启动成功" /bin/true
                                else
                                        action "Nginx启动失败" /bin/false
                                fi
                        fi
                else
                        action "Nginx已经启动了,不要重复启动!" /bin/false
                fi
        ;;

        stop)
        ;;
        status)
        ;;
        *)
                echo "Usage $0 [ start | stop | status ]"
                exit
esac
最后修改日期: 2024年10月25日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。