Linux shell 知识心得03 流程控制if判断+case语句
流程控制之if判断
一:单分支if
语法
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
# 上述语法可以用一行代码代替
[ 条件信息 ] && xxx
示例
[root@simon test]# cat disk_monitor.sh
#!/usr/bin/env bash
disk_use=$(df -P |grep '/$' |awk '{print $5}' |awk -F% '{print $1}')
if [ $disk_use -gt 10 ];then
echo "warning:Not enough hard disk space"
fi
[root@simon test]# . disk_monitor.sh
warning:Not enough hard disk space
注意:if 测试中还可以执行命令 根据命令的返回值做判断
[root@simon ~]# if cd / ;then echo Y ;fi
Y
[root@simon /]# if grep -q root /etc/passwd ;then echo Y ;fi
Y
二:双分支if
语法
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
else
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
# 上述语法可以用一行代码代替
[ 条件信息 ] && xxx || xxxx
示例
#!/bin/bash
username='simon'
password='123'
read -p 'user: ' name
read -p 'passwd: ' passwd
if [ $name = $username -a $passwd = $password ];then
echo 'login successful'
else
echo 'username or password err'
fi
三:多分支if
语法:
if 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
elif 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
elif 条件;then
要执行的命令1
要执行的命令2
要执行的命令3
...
...
else
要执行的命令1
要执行的命令2
要执行的命令3
...
fi
示例1:猜年龄
======================版本1======================
#!/bin/bash
age=87
read -p 'num: ' n
if [ $n -eq $age ];then
echo 'you get it'
elif [ $n -gt $age ];then
echo 'too big'
elif [ $n -lt $age ];then
echo 'too small'
fi
======================版本2======================
#!/bin/bash
read -p ">>> " num
[[ ! $num =~ ^[0-9]+$ ]] && echo "请输入数字" && exit
if [ $num -gt 18 ];then
echo "too big"
elif [ $num -lt 18 ];then
echo "too small"
else
echo "you got it"
fi
示例2:查询成绩
======================版本1======================
#!/bin/bash
read -p 'your score: ' score
if [ $score -ge 90 ];then
echo '优秀'
elif [ $score -ge 70 -a $score -lt 90 ];then
echo '良好'
elif [ $score -ge 60 -a $score -lt 70 ];then
echo '一般'
elif [ $score -lt 60 ];then
echo '较差'
fi
======================版本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
示例3:判断是否是数字
read -p "请输入一个数值: " numwhile :do if [[ $num =~ ^[0-9]+$ ]];then break else read -p "不是数字,请重新输入数值: " num fidoneecho "你输入的数字是: $num"
四 练习
1、编写脚本,命令行传入一个文件路径,判断文件的类型
[root@localhost ~]# cat test_file.sh #!/bin/bashif [ -d $1 ] then echo "$1 is directory"elif [ -b $1 ] then echo "$1 is block"elif [ -f $1 ] then echo "$1 is regular file"else echo 'unknown'fi[root@localhost ~]# ./test_file.sh /etc/passwd/etc/passwd is regular file
2、检测指定的主机是否可以ping通,必须使用$1变量
[root@simon test]# cat ping.sh #!/bin/bashping -c2 $1 &>/dev/nullif [ $? -eq 0 ];then echo "ok"else echo "down"fi[root@simon test]# chmod +x ping.sh [root@simon test]# ./ping.sh 10.10.0.1down[root@simon test]#
3、判断一个用户是否存在
[root@simon test]# cat check_user.sh #!/bin/bashid $1 &> /dev/nullif [ $? -eq 0 ];then echo "user $1 exists"else echo "user $1 not exists"fi[root@simon test]# chmod +x check_user.sh [root@simon test]# ./check_user.sh simonuser simon exists[root@simon test]# ./check_user.sh xxuser xx not exists
4、检测httpd软件是否安装,没有的话则安装
[root@simon test]# cat check_httpd.sh#!/bin/bashrpm -q httpd &>/dev/nullif [ $? -eq 0 ];then echo "已经安装"else echo "正在安装..." yum install httpd -y &>/dev/nullfi
5、判断80端口的状态,未开启则重启
[root@simon test]# cat check_port.sh #!/bin/bashnetstat -an |grep LISTEN |grep '\b80\b' &>/dev/nullif [ $? -eq 0 ];then echo "80端口ok"else echo "80端口down" echo "正在重启..." systemctl restart httpd &> /dev/null if [ $? -eq 0 ];then echo "重启成功" else echo "重启失败" fifi
6、编写监控脚本,如果
根分区剩余空间小于10%
内存的可用空间小于30%
向用户simon发送告警邮件,邮件的内容包含使用率相关信息
答案
[root@simon test]# cat monitor.sh #!/bin/bash#! /bin/bash# 提取根分区剩余空间use_disk=`df / | grep / | awk '{print $5}'`use_percent=`echo $use_disk|cut -d% -f1`# 提取内存剩余空间avail_mem=`free | awk 'NR==2{print $NF}'`total_mem=`free | awk 'NR==2{print $2}'`avail_percent=`echo "scale=2;$avail_mem/$total_mem"|bc | cut -d. -f2`# 注意 磁盘提取的数值单位为 kb、 内存提取的单位为 Mbif [ $use_percent -gt 90 ];then echo "邮件内容:根分区已经使用为${user_disk}低于10%,请及时处理!!!" | mail -s "硬盘报警邮件" rootfiif [ $avail_percent -lt 30 ];then echo "邮件内容:内存剩余${free_percent}%,低于30%" | mail -s "内存报警邮件" xxx@163.comfi
测试:
# 查看163邮箱# [root@simon test]# cat /var/spool/mail/root
mailx配置
[root@simon ~]# yum install mailx -y[root@simon ~]# cat /etc/mail.rcset from=378533872@qq.com set smtp=smtps://smtp.qq.com:465set smtp-auth-user=378533872@qq.comset smtp-auth-password="xxxxxxxxxx"set smtp-auth=loginset ssl-verify=ignoreset nss-config-dir=/etc/pki/nssdb/
解释
set from:设置发件人set smtp:设置外部STMP服务器set smtp-auth-user:设置STMP用户名(一般为完整邮箱地址)set smtp-auth-password:设置SMTP密码,需要登录378533872@qq.com在设置->账户->开启POP3/SMTP服务->获取密码
测试
[root@simon ~]# echo "卧槽" | mail -s "报警邮件" 18611453110@163.com[root@simon ~]# Error in certificate: Peer's certificate issuer has been marked as not trusted by the.
上述报错的解决方式为,依次执行下述命令
mkdir -p /root/.certs/echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/qq.crtcertutil -A -n "GeoTrust SSL CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crtcertutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crtcertutil -L -d /root/.certscd /root/.certscertutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ./ -i qq.crt# 最后出现这句就可以了Notice: Trust flag u is set automatically if the private key is present.# 重新修改配置文件的最后一行[root@simon ~]# cat /etc/mail.rcset from=378533872@qq.com set smtp=smtps://smtp.qq.com:465set smtp-auth-user=378533872@qq.comset smtp-auth-password="xxxxxxxxxx"set smtp-auth=loginset ssl-verify=ignore# set nss-config-dir=/etc/pki/nssdb/ # 改为下面一行set nss-config-dir=/root/.certs# 然后重新测试邮件发送即可
7、根据操作系统不同进行yum源优化 centos6 centos7 centos8
[root@simon shell]# cat check_yum.sh #!/bin/bashmv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup &>/dev/nullvar=$(awk '{print $(NF-1)}' /etc/redhat-release)os_version=`echo ${var%%.*}`if [ $os_version -eq 7 ];then wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/nullelif [ $os_version -eq 6 ];then wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo &>/dev/nullelif [ $os_version -eq 5 ];then wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo &>/dev/nullelse echo "请检查确认系统版本信息"fi
流程控制之case语句
一 语法
case 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后命令序列
esac
二 案例
案例1
#!/bin/bash
read -p "username: " -t 5 username
echo
if [ -z $username ];then
username="default"
fi
case $username in
root)
echo "管理员用户"
;;
simon)
echo "普通用户"
;;
default)
echo "默认用户"
;;
*)
echo "其他用户"
esac
案例2:编写nginx启动脚本
[root@simon shell]# cat nginx_stat.sh
#!/bin/bash
. /etc/init.d/functions
if [ $# -ne 1 ]
then
echo "USAGE $0 {start|stop|restart}"
exit 1
fi
if [ "$1" == "start" ]
then
action "start nginx" /bin/true
elif [ "$1" == "stop" ]
then
action "stop nginx" /bin/true
elif [ "$1" == "restart" ]
then
action "restart nginx" /bin/true
else
echo "USAGE $0 {start|stop|restart}"
exit 1
fi
[root@simon shell]# chmod +x nginx_stat.sh
[root@simon shell]# ./nginx_stat.sh start
start nginx [ 确定 ]
[root@simon shell]# ./nginx_stat.sh restart
restart nginx [ 确定 ]
[root@simon shell]# ./nginx_stat.sh
USAGE ./nginx_stat.sh {start|stop|restart}
案例3:编写nginx启动脚本
# 储备知识1
netstat -lntup|grep ":80\b" # \b锚定单词的结尾
# 储备知识2
action:打印一段信息并执行给定的命令,然后根据给定命令的执行的结果来调用 success,failure方法,确定最终显示的内容
[root@simon shell]# action "nginx start is" :
nginx start is [ 确定 ]
[root@simon shell]# action "nginx start is" /bin/true
nginx start is [ 确定 ]
[root@simon shell]# action "nginx start is" /bin/false
nginx start is [失败]
# 代码
[root@simon shell]# cat nginx_stat.sh
#!/bin/bash
. /etc/init.d/functions
args=$1
fun(){
[ $? -eq 0 ] && action "Nginx $args is " /bin/true || echo "Nginx $args is " /bin/false
}
case $1 in
start)
netstat -an | grep -i Listen | grep -q "\b80\b"
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 -lntup|grep ":80\b" &>/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 -lntup|grep ":80\b" &>/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
案例4:编写一个简易跳板机脚本
# 储备知识
Linux中断信号区别为:键入不同、对应操作不同、启用不同。
1、HUP中断信号:HUP中断信号的对应操作为让进程挂起,睡眠。同<Ctrl+X>
2、INT中断信号:INT中断信号的对应操作为正常关闭所有进程。同<Ctrl+C>
3、TERM中断信号 15:TERM中断信号的对应操作为正常的退出进程。
4、KILL中断信号 9:KILL中断信号的对应操作为强制关闭进程。
5、STOP 19暂停(同 Ctrl + Z)
6、CONT 18继续(与STOP相反, fg/bg命令)
7、TSTP中断信号:TSTP中断信号的对应操作为暂时停用进程。
# 代码
[root@simon shell]# cat jumpserver.sh
#!/bin/bash
cat<<EOF
1. BACKUP 10.0.0.41
2. WEB02 192.168.12.21
3. WEB03 10.0.0.9
EOF
trap "echo 不要乱按键盘,否则服务器将会爆炸" HUP INT TSTP
while true
do
read -p "请输入连接主机编号信息: " num
read -p "请输入账号: " user
# read -p "请输入要执行的命令: " cmd
case $num in
1)
ssh $user@10.0.0.41
[ $? -ne 0 ] && echo "connect faild"
;;
2)
ssh $user@192.168.12.21
[ $? -ne 0 ] && echo "connect faild"
;;
*)
echo "请输入连接主机信息"
esac
done

浙公网安备 33010602011771号