shell流程控制之if 详解


当我们在写程序的时候,经常需要对上一步的执行结果进行判断,那么判断就需要使用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 编写监控脚本,并发邮件

  1. 根分区剩余空间小于10%
  2. 或者内存的可用空间小于30%
  3. 向用户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

2.4 编写 LVS启停脚本

猜你喜欢

转载自blog.csdn.net/m0_46090675/article/details/120475780