内容目录
if判断语句
什么是if
if
就是模仿人类的判断来进行的,但它没有人类那么有情感,只有True
和False
这两种结果
为何要使用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位
- 1.怎么生成随机数,
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
多分支判断语句类似,主要用来做多条件判断- 只不过
case
在shell
脚本中比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
留言