1、if条件语句 条件表达式和if语句可以互相转换
1.1、if 三种类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 if [ -f /etc/hosts ]then echo '文件存在' fi if [ -f /etc/hosts ] then echo "文件存在" else echo "文件不存在" echo "..." >>/tmp/test.logfi if [ -f /etc/hosts ] then echo " hosts文件存在" elif [ -f /etc/host ]then echo " host文件存在" fi
单分支:一个条件一个结果
双分支:一个条件两个结果
多分支:多个条件多个结果
1.2、【练习题1】输入2个数字,比较大小(使用if语句结合条件表达式实现) 说明:3个脚本:使用直接赋值,传参,read任一种方法写3种脚本(单分支,双分支,多分支)
示例脚本一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [lepeng@centos ~]#!/bin/bash read -p "请输入第一个整数:" NUM1 expr 1 + $NUM1 &>/dev/nullif [ $? -eq 2 ] then echo "$NUM1 不是整数 " exit 2fi read -p "请输入第二个整数:" NUM2 expr 1 + $NUM2 &>/dev/null if [ $? -eq 2 ] then echo "$NUM2 不是整数 " exit 2fi if [ $NUM1 -eq $NUM2 ]then echo "$NUM1 = $NUM2 " exit fi if [ $NUM1 -gt $NUM2 ] then echo "$NUM1 > $NUM2 " exit fi if [ $NUM1 -lt $NUM2 ]then echo "$NUM1 < $NUM2 " fi
示例脚本二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [lepeng@centos ~]#!/bin/bash read -p "请输入第一个整数:" NUM1 expr 1 + $NUM1 &>/dev/nullif [ $? -eq 2 ] then echo "$NUM1 不是整数 " exit 2fi read -p "请输入第二个整数:" NUM2 expr 1 + $NUM2 &>/dev/null if [ $? -eq 2 ] then echo "$NUM2 不是整数 " exit 2fi if [ $NUM1 -eq $NUM2 ]then echo "$NUM1 = $NUM2 " exit else if [ $NUM1 -gt $NUM2 ] then echo "$NUM1 > $NUM2 " exit else if [ $NUM1 -lt $NUM2 ] then echo "$NUM1 < $NUM2 " fi fi fi
示例脚本三:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [lepeng@centos ~]#!/bin/bash read -p "请输入第一个整数:" NUM1 expr 1 + $NUM1 &>/dev/null NUM1_FH=$? if [ $NUM1_FH -eq 2 ] then echo "$NUM1 不是整数 " exit 2else read -p "请输入第二个整数:" NUM2 expr 1 + $NUM2 &>/dev/null NUM2_FH=$? if [ $NUM2_FH -eq 2 ] then echo "$NUM2 不是整数 " exit 2 fi fi if [ $NUM1 -eq $NUM2 ]then echo "$NUM1 = $NUM2 " exit elif [ $NUM1 -gt $NUM2 ]then echo "$NUM1 > $NUM2 " exit elif [ $NUM1 -lt $NUM2 ]then echo "$NUM1 < $NUM2 " fi
1.3、【练习题2】系统内存低于100M邮件报警,加入计划任务,3分钟检查一次。 对于开发程序而言,一般来说应该遵循下面的3步法则。
分析需求。明白开发需求,是完成程序的大前提,因此,分析需求至关重要,一切不以需求为主的程序开发,都是耍流氓的!
设计思路。设计思路就是根据需求,把需求进行拆解,分模块逐步实现,例如本题可以分为如下几步:
获取当前系统剩余内存的值(先在命令行实现)。
配置邮件报警(可采用第三方邮件服务器)。
判断取到的值是否小于100MB,如果小于100MB,就报警(采用if语句)。
编码实现Shell脚本。
加入crond定时任务,每三分钟检查一次。
编码实现。编码实现就是具体的编码及调试过程,工作中很可能需要先在测试环境下调试,调试好了,再发布到生产环境中。
第一步:先配置邮件服务,保证能够发生邮件
1 echo 'set from=mail@znix.top smtp=smtp.znix.top smtp-auth-user=mail@znix.top smtp-auth-password=****** smtp-auth=login' >> /etc/mail.rc
发送测试邮件发送
1 echo "`date +%F_%T`" |mail -s "这是测试邮件" admin@znix.top
第二步编写检查脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [lepeng@centos ~]#!/bin/bash Mem=`free -m |awk 'NR==2{print $NF}' ` host=`hostname` Ip=`hostname -I` Date=`date +%F_%T` mail_file=/tmp/mail.s dest_user=admin@znix.top if [ $Mem -lt 100 ]then echo "发生时间: $Date " >$mail_file echo "发生主机: $host 主机IP地址: $Ip " >> $mail_file echo "内存余量: $Mem M" >> $mail_file mail -s "【警告】内存不足了呀!" $dest_user < $mail_file fi
第三步测试脚本(可以修改判断的值)
第四步 脚本测试成功,写入定时任务
1 2 3 [[lepeng@centos ~] */3 * * * * /bin/sh /server/scripts/panduan/mem_info.sh &>/dev/null
至此,一个监控脚本就写好了
1.4、【练习题3】模拟编写启动nginx脚本 脚本内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [lepeng@centos ~]#!/bin/bash . /etc/init.d/functions StartCheck=`netstat -lntup |grep -c 80` StartCMD='/application/nginx/sbin/nginx ' StopCMD='/application/nginx/sbin/nginx -s stop ' StatusCheck=`netstat -lntp|grep -c nginx` ReloadCMD='/application/nginx/sbin/nginx -s reload' CheckCMD='/application/nginx/sbin/nginx -t' UsaGe="Usage: $0 {start|stop|status|reload|check}" COMMAND=$1 if [ $# -ne 1 ] then echo $UsaGe && exit 2fi if [ $COMMAND = start ] then if [ $StartCheck == 1 ] then action "启动Nginx失败,端口被占用" /bin/false else $StartCMD action "启动Nginx" /bin/true fi elif [ $COMMAND = stop ]then $StopCMD &>/dev/null if [ $? -eq 0 ] then action "停止Nginx" /bin/true else action "停止Nginx" /bin/false fi elif [ $COMMAND = status ]then if [ $StatusCheck -eq 1 ] then echo "nginx 正在运行..." else echo "Nginx 未运行." fi elif [ $COMMAND = reload ] then $ReloadCMD action "reload" /bin/true elif [ $COMMAND = check ]then $CheckCMD else echo $UsaGe exit 2fi
脚本执行过程:
1.5【练习题4】Web及MySQL服务异常监测案例 用if条件语句实现对Nginx Web服务以及MySQL数据库服务是否正常进行检测,如果服务未启动,则启动相应服务。
脚本编写思路:
判断web服务器正常
进程 ps -ef |grep nginx
端口 netstat ss losf telnet nc nmap
curl 页面 返回值
curl check.html 的内容
判断mysql服务器正常
端口 netstat ss losf telnet nc nmap
进程 ps -ef |grep mysql
mysql 登录访问看一下
mysql insert一个数据 select一个数据
web服务监控脚本示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [lepeng@centos ~]#!/bin/bash . /etc/init.d/functions JinChen=`ps -ef |grep -c [n]ginx` QiDong='/server/scripts/nginx.sh start' StatuS=`curl -I -w "%{http_code}\n" -o /dev/null -s 10.0.0.180` StatuS2=`curl -s 10.0.0.180/check.html|grep -c ok` StartNginx='/server/scripts/nginx.sh start' if [ $JinChen -ge 2 ]then if [ "$StatuS " -eq 200 ] then if [ "$StatuS2 " -eq 1 ] then action "Nginx 服务运行正常" /bin/true else action "请检查chenk.html文件!" /bin/false fi else action "请检查首页文件!" /bin/false fi else action "Nginx 未正常运行!" /bin/false $StartNginx fi
脚本执行过程:
2、case条件结构语句 2.1、case语法结构 1 2 3 4 5 6 7 8 9 10 case "字符串变量" in 值1) 指令1 ;; 值2) 指令2 ;; 值*) 指令esac
2.2、case 值的书写方式 1 2 3 4 5 6 7 8 9 apple) echo -e "$RED_COLOR apple $RES " ;; apple|APPLE) echo -e "$RED_COLOR apple $RES " ;;
2.3、case语句小结
case语句就相当于多分支的if语句。case语句的优势是更规范、易读。
case语句适合变量的值少,且为固定的数字或字符串集合。(1,2,3)或(start,stop,restart)。
系统服务启动脚本传参的判断多用case语句,多参考rpcbind/nfs/crond脚本;菜单脚本也可以使用case
2.4、【练习题1】使用case编写一个菜单脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [lepeng@centos ~]#!/bin/bash cat<<EOF 1. install rsync 2. install nfs 3. install mysql 4. install all EOF read -p '请输入你的选择:' chs case $chs in 1) echo install rsync success ;; 2) echo install nfs success ;; 3) echo install mysql success ;; 4) echo install rsync/nfs/mysql success ;; *) echo "你输入有误" esac
脚本执行过程:
2.5、if 与 case 对比
if 语句类似黑名单,需要把这种错误场景封堵。
case 语句类似白名单,只要把正确结果列完整即可。
3、for循环语句 在计算机科学中,for循环(英语:for loop)是一种编程语言的迭代陈述,能够让程式码反复的执行。
它跟其他的循环,如while循环,最大的不同,是它拥有一个循环计数器,或是循环变数。这使得for循环能够知道在迭代过程中的执行顺序。
3.1、shell中的for循环 shell中的 for 循环与在c中不同,它包含三种形式:第一种结构是列表 for 循环
;第二种结构就是不带列表的for循环;第三种就类似于C语言。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 for i in 取值列表do 循环主体/命令done #!/bin/absh for i do echo "$i " done [lepeng@centos ~] http://blog.znix.topfor ((exp1;exp2;exp3))do 指令...done for ((i=0;i<=3;i++))do echo $i done
3.2、不同语言的For循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 for i in 1 2 3 do echo $i done for i in 1 2 3;do echo $i ;done for (int i = 0; i < 5; i++){ //循环语句; }for ($i = 0; $i < 5; $i ++) { }
3.3、【练习题1】批量生成随机字符文件名案例 使用for循环在/clsn目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串clsn,名称示例如下:
1 apquvdpqbk_clsn .html mpyogpsmwj_clsn .html txynzwofgg_clsn .html bmqiwhfpgv_clsn .html udrzobsprf_clsn .html vjxmlflawa_clsn .html jhjdcjnjxc_clsn .html qeztkkmewn_clsn .html jpvirsnjld_clsn .html ruscyxwxai_clsn .html
脚本内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [lepeng@centos ~]#!/bin/bash [ -d /clsn ] || mkdir -p /clsn rpm -qa |grep pwgen &>/dev/nullif [ $? -eq 1 ] then yum install pwgen -y &>/dev/nullfi cd /clsn &&\for i in {1..10} do File_Name2=`pwgen -1A0 10` touch ${File_Name2} _clsn.htmldone
3.4、【练习题2】批量改名特殊案例 【练习题1】中结果文件名中的clsn字符串全部改成znix(最好用for循环实现),并且将扩展名html全部改成大写。jpvirsnjld_clsn.html ===> jpvirsnjld_znix.HTML
脚本内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [lepeng@centos ~]#!/bin/bash cd /clsn &&\ File_name=`ls |sed -r 's#(.*)_clsn.html#\1#g' ` for i in $File_name do if [ -f ${i} _clsn.html ] then mv ${i} _clsn.html ${i} _znix.HTML else echo "文件修改完成." exit fi done
批量改名其他方式
1 2 3 4 5 rename txt jpg * ls *jpg|sed -r 's#(.*).jpg#mv & \1.mp4#' |bash
4、while循环语句 在编程语言中,while循环(英语:while loop)是一种控制流程的陈述。利用一个返回结果为布林值(Boolean)的表达式作为循环条件,当这个表达式的返回值为“真”(true)时,则反复执行循环体内的程式码;若表达式的返回值为“假”(false),则不再执行循环体内的代码,继续执行循环体下面的代码。
因为while循环在区块内代码被执行之前,先检查陈述是否成立,因此这种控制流程通常被称为是一种前测试循环(pre-test loop)。相对而言do while循环,是在循环区块执行结束之后,再去检查陈述是否成立,被称为是后测试循环。
4.1、shell中while语法
4.2、while 使用场景,多用于创建守护进程 【示例1】while实现web服务器搭建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [lepeng@centos ~]#!/bin/bash while true do echo "ok" | nc -l 81done [root@clsn html] ok [lepeng@centos ~] GET / HTTP/1.1 User-Agent: curl/7.29.0 Host: 10.0.0.180:81 Accept: */*
【示例2】:while创建定时任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/bin/bash while true do uptime sleep 0.6done [lepeng@centos ~] 15:01:52 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05 15:01:53 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05 15:01:53 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05 15:01:54 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05 15:01:55 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05 15:01:55 up 2 days, 6:02, 3 users, load average: 0.00, 0.01, 0.05
说明:
sleep 单位 秒 sleep 1 休息1秒
usleep 单位 微秒 usleep 1000000 休息1s
1微秒等于百万分之一秒(10的负6次方秒)
【示例3】:计算1-100的和
方法一 (bc命令实现)
1 echo `seq -s + 1 100`|bc
方法二(while循环方法)
1 2 3 4 5 6 7 8 9 10 11 [lepeng@centos ~]#!/bin/bash i=1 while [ "$i " -le 100 ]do ((b=b+i)) ((i++))done echo $b
示例3:实现类似手机通讯计费功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [lepeng@centos ~]#!/bin/bash sum=1000 i=15while [ $sum -ge 15 ]do cat<<EOF ================= 1.发短信 2.查余额 3.账户充值 4.退出 ================= EOF read -p "你要做什么呢?" Some case "$Some " in 1) sum=$((sum-i)) read -p "请输入发送短信的内容:" read -p "请输入收信人:" sleep 0.3 echo "发送成功." echo "您当前余额为$sum " ;; 2) echo "您当前余额为$sum " ;; 3) read -p "请输入你要充值的金额:" ChongZhi sum=$((sum+ChongZhi)) echo "充值成功,当前余额为$sum " ;; 4) exit ;; *) echo "输入有误!" exit 2 esac done echo "余额不足,请及时充值!"
5、break continue exit return 条件与循环控制及程序返回值命令表
命令
说明
break n
如果省略n,则表示跳出整个循环,n表示跳出循环的层数
continue n
如果省略n,则表示跳过本次循环,忽略本次循环的剩余代码,进人循环的下一次循环;n表示退到第n层继续循环
exit n
退出当前Shell程序,n为上一次程序执行的状态返回值。n也可以省略,在下一个Shell里可通过”$?”接收exit n的n值
return n
用于在函数里作为函数的返回值,以判断函数执行是否正确。在下一个Shell里可通过”$?”接收exit n的n值
简单来说即:
break 跳出循环
continue 跳出本次循环
exit 退出脚本
return 与 exit 相同,在函数中使用
5.1、break命令说明 1 2 3 4 5 6 7 break : break [n] 退出 for 、while 、或 until 循环 退出一个 FOR 、WHILE 或 UNTIL 循环。如果指定了N,则打破N重循环 退出状态: 退出状态为 0 除非 N 不大于或等于 1 。
5.2、continue命令说明 1 2 3 4 5 6 7 8 continue : continue [n] 继续 for 、while 、或 until 循环。 继续当前 FOR 、WHILE 或 UNTIL 循环的下一步。 如果指定了 N, 则继续当前的第 N 重循环。 退出状态: 退出状态为 0 除非 N 不大于或等于1 。
5.3、exit命令说明 1 2 3 4 5 exit : exit [n] 退出shell。 以状态 N 退出 shell。 如果 N 被省略,则退出状态 为最后一个执行的命令的退出状态。
5.4、return 命令说明 1 2 3 4 5 6 7 8 9 return: return [n] 从一个 shell 函数返回。 使一个函数或者被引用的脚本以指定的返回值 N 退出。 如果 N 被省略,则返回状态就是 函数或脚本中的最后一个执行的命令的状态。 退出状态: 返回 N,或者如果 shell 不在执行一个函数或引用脚本时,失败。