shell 流程控制
场景实践二:查看磁盘/分区当前使用状态,如果使用率超过80%则报警发邮件
[root@shell shell]# cat disk.sh
#!/bin/bash
#定义变量
Disk_Use=$(df -h |awk '/\/$/{print $(NF-1)}')
#根据磁盘的使用率情况进行判断
if [ ${Disk_Use/\%/} -gt 7 ];then
echo "当前主机$(hostname) 磁盘根分区使用率不正常,使用率为:$Disk_Use"
else
echo "当前主机$(hostname) 磁盘根分区使用率正常,使用率为:$Disk_Use"
fi
[root@shell shell]# cat disk.sh
#!/bin/bash
#定义变量
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
Disk_Use=$(df -h |awk '/\/$/{print $(NF-1)}')
#根据磁盘的使用率情况进行判断
if [ ${Disk_Use/\%/} -gt 80 ];then
action "当前主机$(hostname) 磁盘根分区使用率不正常,使用率为:$Disk_Use" /bin/false
else
action "当前主机$(hostname) 磁盘根分区使用率正常,使用率为:$Disk_Use" /bin/true
fi
场景实践三:条件测试,创建用户
[root@shell shell]# cat cre_user.sh
#!/bin/bash
#提示用户输入要创建的用户
read -p "请输入你要创建的用户:" user
#判断该用户是否存在系统,如果不存在,则创建
id $user &>/dev/null
#根据上条命令的执行结果进行判断是否需要创建用户
if [ $? -eq 0 ];then
echo "该用户$user 已经存在!"
else
read -p "该用户$user 不存在该系统,你是否确认创建{Y|N}:" re
if [ $re == "Y" ];then
useradd $user &>/dev/null
if [ $? -eq 0 ];then
echo "用户$user 创建成功!"
else
echo "用户$user 创建失败!"
fi
elif [ $re == "N" ];then
echo "你选择不创建!再见!"
else
echo "你没有按照要求输入,请输入:[Y|N]"
exit
fi
fi
场景实践四:函数库使用,判断url地址是否能通
[root@shell shell]# cat url.sh
#!/bin/bash
#调用函数库
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
#提示用户输入一个url地址进行测试
read -p "请输入一个要测试的url地址:" Url
#根据用户输入的url进行测试
ping -c1 -W1 $Url &>/dev/null
#根据测试的结果进行判断连通性
if [ $? -eq 0 ];then
action "你要测试的url地址:$Url 是可以连通的!" /bin/true
else
action "你要测试的url地址:$Url 是不可以连通的!" /bin/false
fi
if字符比较
选项 说明 示例
== 等于则条件为真 [ "$a" == "$b" ]
!= 不相等则条件为真 [ "$a" != "$b" ]
-z 字符串的长度为零则为真 [ -z "$a" ]
-n 字符串的长度不为零则为真 [ -n "$a" ]
[root@shell shell]# [ $USER == "root" ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ $USER == "roo" ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ $USER != "roo" ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ $USER != "root" ] && echo "为真" || echo "为假"
为假
[root@shell shell]# name=''
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# name=1
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ -n $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# name=''
[root@shell shell]# [ -n $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# cat if-3.sh
#!/bin/bash
read -p "请输入一个[yes]:" input
if [ $input == "yes" ];then
echo "OK"
else
echo "ERR"
fi
[root@shell shell]# cat if-3.sh
#!/bin/bash
read -p "请输入一个[yes]:" input
if [ $input == "yes" ];then
echo "OK"
else
echo "ERR"
fi
read -p "请输入一个[yes]:" zimu
if [ $zimu != "ok" ];then
echo "OK"
else
echo "ERR"
fi
多整数进行比较
-a 并且
-o 或者
[root@shell shell]# [ 1 -gt 10 -a 2 -lt 1 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -a 2 -lt 1 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -a 2 -gt 1 ] && echo "正确" || echo "错误"
正确
[root@shell shell]# [ 10 -gt 10 -a 2 -gt 1 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 10 -gt 10 -o 2 -gt 1 ] && echo "正确" || echo "错误"
正确
[root@shell shell]# [ 10 -gt 10 -o 2 -gt 10 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -o 2 -gt 1 ] && echo "正确" || echo "错误"
正确
&& 并且
|| 或者
必须要用双[]号
[root@shell shell]# [[ 11 -gt 10 && 2 -gt 1 ]] && echo "正确" || echo "错误"
正确
[root@shell shell]# [[ 11 -lt 10 && 2 -gt 1 ]] && echo "正确" || echo "错误"
错误
[root@shell shell]# [[ 9 -lt 10 && 2 -gt 10 ]] && echo "正确" || echo "错误"
错误
[root@shell shell]# [[ 9 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
正确
[root@shell shell]# [[ 11 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
错误
[root@shell shell]# [[ 9 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
正确
场景实践:根据学生录入的成绩判断,学生的优劣
1-59 补考,60-80 合格,80-100 优秀
执行脚本
提示用户输入一个分数
单条件
[root@shell shell]# cat score-1.sh
#!/bin/bash
#提示用户输入要查询的成绩
read -p "请输入你要查询的成绩:" fs
#根据用户输入的分数进行判断
if [ $fs -gt 100 ];then
echo "你是不是查错学科了,本学科满分100."
elif [ $fs -ge 80 ];then
echo "优秀"
elif [ $fs -ge 60 ];then
echo "及格"
elif [ $fs -lt 60 ];then
echo "补考"
else
echo "请输入一个整数"
fi
多条件
[root@shell shell]# cat score.sh
#!/bin/bash
#提示用户输入一个分数
read -p "请输入你要查询的成绩:" fs
#根据用户输入的分数进行判断
if [ $fs -ge 0 -a $fs -lt 60 ];then
echo "补考!"
elif [ $fs -ge 60 -a $fs -lt 80 ];then
echo "及格"
elif [ $fs -ge 80 -a $fs -le 100 ];then
echo "优秀"
elif [ $fs -gt 100 ];then
echo "你是不是查错学科了,本学科满分100."
else
echo "请输入一个整数"
fi
[root@shell shell]# cat score-1.sh
#!/bin/bash
#提示用户输入要查询的成绩
read -p "请输入你要查询的成绩:" fs
#判断用户输入是否为空值
[ -z $fs ] && echo "请不要尝试回车,不支持!" && exit
#判断用户输入的是否为数字
expr 1 + $fs &>/dev/null
#根据上条命令进行判断
if [ $? -ne 0 ];then
echo "请输入一个数字"
exit
fi
#根据用户输入的分数进行判断
if [ $fs -gt 100 ];then
echo "你是不是查错学科了,本学科满分100."
elif [ $fs -ge 80 ];then
echo "优秀"
elif [ $fs -ge 60 ];then
echo "及格"
elif [ $fs -lt 60 ];then
echo "补考"
else
echo "请输入一个整数"
fi
if正则比较
[root@shell shell]# [ $USER =~ root ] && ec
ho "OK" || echo "ERR"
-bash: [: =~: binary operator expected
ERR
[root@shell shell]# [[ $USER =~ root ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# [[ $USER =~ ^r ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=roo
[root@shell shell]# [[ $name =~ ^r ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=123
[root@shell shell]# [[ $name =~ ^r ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=123a
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# name=ok
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# [[ $name =~ ^[a-Z]+$ ]] && echo "OK" || echo "ERR"
OK
示例一:判断用户输入的是否为整数
[root@git shell]# cat num1.sh
#!/bin/bash
read -p "输入一个整数" num
if [[ ! "$num" =~ ^[0-9]+$ ]]; then
echo "请输入整数!!!"
exit
fi
echo "输入正确 $num"
示例二:写一个创建用户的脚本,需要输入创建用户的前缀,比如oldboy,以及后缀。比如123。
[root@shell shell]# cat user-1.sh
#!/bin/bash
#提示用户输入一个前缀,只能是字母
read -p "请输入你要创建用户的前缀,只能是字母:" qz
#根据用户输入的前缀进行判断是否为字母
if [[ ! $qz =~ ^[a-Z]+$ ]];then
echo "请输入正确的前缀,只能是字母"
exit
fi
#提示用户输入一个后缀
read -p "请输入你要创建用户的后缀,只能是数字:" hz
#根据用户输入的后缀进行判断是否为数字
if [[ ! $hz =~ ^[0-9]+$ ]];then
echo "请输入正确的后缀,只能是数字"
exit
fi
#满足条件则开始创建用户
user=${qz}${hz}
#判读该用户是否存在
id $user &>/dev/null
#根据命令执行结果进行判断
if [ $? -eq 0 ];then
echo "该用户$user 已经存在!"
else
useradd $user &>/dev/null
#判断用户是否创建成功
if [ $? -eq 0 ];then
echo "用户$user 创建成功!"
else
echo "用户$user 创建失败!"
fi
fi
1.场景示例:使用root用户清空/var/log/messages日志,并每次执行保留最近100行
[root@shell shell]# cat message.sh
#!/bin/bash
#判断当前用户是否是root
if [ ! $USER == "root" ] && [ ! $UID -eq 0 ];then
echo "该用户$USER 对该脚本$0 没有执行权限"
exit
fi
File=/var/log/messages
#判断/var/log/messages是否存在
if [ ! -f $File ];then
echo "$File 该文件不存在!"
exit
fi
#清空日志,但要保留最后的100行
tail -100 $File >${File}.bak
#清空日志,删除.bak的文件
cat ${File}.bak >$File && rm -f ${File}.bak
if [ $? -eq 0 ];then
echo "日志$File 清除成功!"
else
echo "日志$File 清除失败!"
fi
2.场景示例:判断sshd服务是否正常启动
判断是否启动
systemctl status sshd
#判断端口是否存在
netstat -lntp|grep sshd
#判断进程是否存在
ps aux|grep sshd
[root@shell shell]# cat if-4.sh
#!/bin/bash
#判断用户必须要输出位置变量
if [ $# -ne 1 ];then
echo "请输入一个要查询的服务。"
echo "Usage: $0 {sshd|nginx|php-fpm|mysql}"
exit
fi
#判断服务是否在运行
state=$(systemctl status $1 |awk '/Active/{print $2}')
#根据变量值进行判断
if [ $state == "active" ];then
echo "服务$1 正在运行....."
else
echo "服务$1 不在运行,当前状态为:$state "
fi
#判断端口是否存在
netstat -lntp |grep $1 &>/dev/null
#根据上条命令返回值进行判断
if [ $? -eq 0 ];then
echo "服务$1 端口存在!"
else
echo "服务$1 端口没有启动!请你检查一下。"
fi
#判断进程是否存在
ps aux|grep $1 |grep -v grep | grep -v pts &>/dev/null
#根据上条命令的返回值进行判断
if [ $? -eq 0 ];then
echo "服务$1 进程存在!"
else
echo "服务$1 进程不存在!"
fi
3.安装不同的yum源
[root@shell shell]# cat yum.sh
#!/bin/bash
#定义变量
Ver=$(cat /etc/redhat-release |awk '{print $(NF-1)}')
#根据变量值的结果进行判断
if [ ${Ver%%.*} -eq 6 ];then
#安装centos-6系列的yum源
#清空旧的yum源
rm -f /etc/yum.repos.d/* &>/dev/null
#安装base源
echo "你的操作系统为:$Ver ,开始安装${Ver%%.*}的Base源"
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo &>/dev/null
if [ $? -eq 0 ];then
echo "$Ver 系统的Base安装成功!"
else
echo "$Ver 系统的Base安装失败!"
fi
#安装epel源
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo &>/dev/null
if [ $? -eq 0 ];then
echo "$Ver 系统的Epel安装成功!"
else
echo "$Ver 系统的Epel安装失败!"
fi
elif [ ${Ver%%.*} -eq 7 ];then
#安装centos-7系列的yum源
#清空旧的yum源
rm -f /etc/yum.repos.d/* &>/dev/null
#安装base源
echo "你的操作系统为:$Ver ,开始安装${Ver%%.*}的Base源"
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/null
if [ $? -eq 0 ];then
echo "$Ver 系统的Base安装成功!"
else
echo "$Ver 系统的Base安装失败!"
fi
#安装Epel源
echo "你的操作系统为:$Ver ,开始安装${Ver%%.*}的Epel源"
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo &>/dev/null
if [ $? -eq 0 ];then
echo "$Ver 系统的Epel安装成功!"
else
echo "$Ver 系统的Epel安装失败!"
fi
else
echo "你的操作系统不符合我们的要求。"
exit
fi
case语句
case用来实现对程序流程的选择、循环等进行控制。语法如下:
case 变量 in
变量1)
命令序列 1;;
变量2)
命令序列 2;;
变量3)
命令序列 3;;
*)
无匹配后命令序列
esac
安装PHP的不同版本
菜单
1、安装PHP 5.5 版本
2、安装PHP 5.6 版本
3、安装PHP 7.0 版本
4、退出
[root@shell shell]# cat case-1.sh
#!/bin/bash
#定义菜单
cat << EOF
######################
1、安装PHP 5.5 版本
2、安装PHP 5.6 版本
3、安装PHP 7.0 版本
4、退出
######################
EOF
#根据上方菜单进行选择要安装PHP版本
read -p "请选择你要安装的PHP版本,请输入对应的数字:" install
case $install in
1)
echo "你选择安装PHP版本为5.5."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 5.5 已经安装完成!"
;;
2)
echo "你选择安装PHP版本为5.6."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 5.6 已经安装完成!"
;;
3)
echo "你选择安装PHP版本为7.0."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 7.0 已经安装完成!"
;;
4)
exit
;;
*)
echo "请输入数字[1-4],不能乱输!"
esac
场景示例一:写一个rsync的启动和停止的脚本
怎么启动rsync
/usr/bin/rsync --daemon
怎么停止
pkill rsync
[root@shell shell]# cat case-2.sh
#!/bin/bash
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
#判断用户是否输入一个位置变量
if [ $# -ne 1 ];then
echo "请输入一个参数,具体使用方法如下:"
echo "Usage: $0 {start|stop|status|restart}"
exit
fi
#编写case语句
state=$1
Rsync=/var/run/rsync.pid
case $state in
start)
if [ -f $Rsync ];then
action "Rsync 正在运行...." /bin/false
else
touch $Rsync
/usr/bin/rsync --daemon &>/dev/null
if [ $? -eq 0 ];then
action "Rsync 服务启动成功!" /bin/true
else
action "Rsync 服务启动失败!" /bin/false
fi
fi
;;
stop)
if [ -f $Rsync ];then
rm -f $Rsync && pkill rsync &>/dev/null
if [ $? -eq 0 ];then
action "Rsync 服务关闭成功!" /bin/true
else
action "Rsync 服务关闭失败!" /bin/false
fi
else
action "Rsync 服务没有运行!" /bin/false
fi
;;
status)
if [ -f $Rsync ];then
action "Rsync 服务正在运行...." /bin/true
else
action "Rsync 服务没有运行...." /bin/true
fi
;;
restart)
if [ -f $Rsync ];then
rm -f $Rsync && pkill rsync &>/dev/null
if [ $? -eq 0 ];then
action "Rsync 服务关闭成功!" /bin/true
else
action "Rsync 服务关闭失败!" /bin/false
fi
else
action "Rsync 服务没有运行!" /bin/false
fi
touch $Rsync
/usr/bin/rsync --daemon &>/dev/null
if [ $? -eq 0 ];then
action "Rsync 服务启动成功!" /bin/true
else
action "Rsync 服务启动失败!" /bin/false
fi
;;
*)
echo "请输入一个参数,具体使用方法如下:"
echo "Usage: $0 {start|stop|status|restart}"
exit
esac
2.场景示例二:编写一个nginx的启动和停止脚本。
1.如何启动 /usr/sbin/nginx
2.如何停止 /usr/sbin/nginx -s stop
3.如何重载 /usr/sbin/nginx -s reload
3.场景示例三:实现系统管理工具箱
[root@git jiaoben]# cat menm.sh
#!/bin/bash
cat << EOF
#############
1.查看内存
2.查看磁盘信息
3.我是谁
4.联网
5.创建文件
6.什么都不想干
#############
EOF
read -p "输入数字" a
case $a in
1)
mem=$(free -m |awk 'NR==2 {print $3}')
echo "剩余内存有$mem"
;;
2) df=$(df -h | awk 'NR==2 {print $5}')
echo "剩余磁盘有$df"
;;
3) who=$(hostname)
echo "我叫$who"
;;
4) ping=$(ping -c 3 -W 1 baidu &>/dev/null )
echo "我可以联网哟"
;;
5)
read -p "输入想创的文件名" txt
mkdir $txt &>/dev/null
if [ $? -eq 0 ];then
echo "该用户$txt 创建成功!!!!"
elif [ $? -eq 1 ];then
echo "该用户$txt 已存在了哟!!!!"
fi
;;
6) echo "我什么都不想干 ,再见!!!"
;;
*)
echo "你输错了哟......."
esac
4.场景示例四:实现简单的JumpServer
1.执行脚本后,需要看到所有我能管理的主机
2.有一个选择菜单,提示输入连接某个主机
3.需要写一个死循环,保证程序连接后端服务,退出后还能接着选择主机。
4.不能让跳板机直接ctrl+c ctrl+z退出了,trap 控制ctrl+c ctrl+z的信号
5.退出服务器的会话,再次登录,又可以正常操作服务器。将脚本加入到/etc/bashrc中,当用户一连接,自动就运行该脚本。
#!/usr/bin/bash
meminfo(){
cat <<-EOF
-------------------------------
| 1) db01-172.16.1.52 |
| 2) db02-172.16.1.53 |
| 3) db02-172.16.1.54 |
| h) help |
---------------------------------
EOF
}
meminfo
read -p "请输入你需要连接的主机序号[1|2|3|..]: " connection
case $connection in
1)
ssh root@172.16.1.52
;;
2)
ssh root@172.16.1.53
;;
3)
ssh root@172.16.1.54
;;
h)
clear
meminfo
;;
exec)
exit
;;
*)
echo "USAGE: $0 输入连接的主机编号即可 [ 1 | 2 | 3 | ]"
esac
#加强版
[root@qiudao /scripts]# cat jumpserver2.sh
#!/usr/bin/bash
meminfo(){
cat <<-EOF
-------------------------------
| 1) db01-172.16.1.52 |
| 2) db02-172.16.1.53 |
| 3) db02-172.16.1.54 |
| h) help |
---------------------------------
EOF
}
meminfo
trap "" HUP INT TSTP #控制不让输出Ctrl+c,z
while true
do
read -p "请输入你需要连接的主机序号[1|2|3|..]: " connection
case $connection in
1)
ssh root@172.16.1.52
;;
2)
ssh root@172.16.1.53
;;
3)
ssh root@172.16.1.54
;;
h)
clear
meminfo
;;
exec)
exit
;;
*)
echo "USAGE: $0 输入连接的主机编号即可 [ 1 | 2 | 3 | ]"
esac
done
05. 场景示例五:实现多级菜单功能
[root@web01 ~]# cat case-7.sh
#!/usr/bin/bash
mem_option (){
cat <<-EOF
---------主菜单----------
| 1) 安装nginx |
| 2) 安装php |
| 3) 退出 |
--------------------------
EOF
}
mem_install_nginx(){
cat <<-EOF
-----Installed Nginx -----
| 1) 安装nginx1.1 |
| 2) 安装nginx1.2 |
| 3) 安装nginx1.3 |
| 4) 返回上一页 |
--------------------------
EOF
}
mem_install_php(){
cat <<-EOF
--------------------------
| 1) 安装php5.5 |
| 2) 安装php5.6 |
| 3) 安装php7.0 |
| 4) 返回上一页 |
--------------------------
EOF
}
#----------------------------------------------------------------------
while true
do
mem_option
read -p "请输入主菜单需要选择的选项,使用方法[1|2|3]: " option
case $option in
1)
clear
while true
do
mem_install_nginx
read -p "请输入你要安装Nginx的Version: " nginx_install_option
case $nginx_install_option in
1)
clear
echo "Installed Nginx Version 1.1 is Done....."
sleep 1
;;
2)
clear
echo "Installed Nginx Version 1.2 is Done....."
sleep 1
;;
3)
clear
echo "Installed Nginx Version 1.3 is Done....."
sleep 1
;;
4)
clear
break
;;
esac
done
;;
2)
clear
while true
do
mem_install_php
read -p "请输入你要选择的php Version: " php_install_option
case $php_install_option in
1)
clear
echo "Installed php Version 5.5 is Done....."
sleep 1
;;
2)
clear
echo "Installed php Version 5.6 is Done....."
sleep 1
;;
3)
clear
echo "Installed php Version 5.7 is Done....."
sleep 1
;;
4)
clear
break
;;
*)
esac
done
;;
3)
exit
;;
*)
echo "USAGE: [ 1 | 2 |3 ]"
esac
done
5.场景示例五:实现多级菜单功能
cat <<-EOF
===================
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
=====================
EOF
read -p "请输入你需要做的操作: " sys
case $sys in
f)
df -h
;;
d)
mount -a |less
;;
u)
w
;;
q)
exit
;;
*)
echo "你输错了哟......."
esac
瞎写的
[root@git shell]# cat city.sh
#!/bin/bash
cat << EOF
============
1) 温州 |
2)杭州 |
3)苏州 |
4)上海 |
5)北京
6) 退出 |
============
EOF
read -p "输入对应的数字" city
case $city in
1)
echo " 温州是个好地方....."
;;
2)
echo "杭州西湖......"
;;
3)
echo " 苏州园林....."
;;
4) echo "上海 豫园...."
;;
5) echo "北京天安门..."
;;
6) echo " 再见....."
;;
*)
echo "你输错了哟......."
esac