本文共 10438 字,大约阅读时间需要 34 分钟。
在bash编程中,条件测试常用的语法形式如下表:
说明⚠️:
test语法格式:test<测试表达式>
[root@wtf tmp]# test -s file.txt && echo "true" || echo "false"false[root@wtf tmp]# test -s seq.txt && echo "true" || echo "false"true
说明⚠️:
test命令若执行成功(为真),则执行 && 后面的命令,反之执行 || 后面的命令。
[root@wtf tmp]# test -z "wutf" && echo "true" || echo "false"false[root@wtf tmp]# test -z " " && echo "true" || echo "false"false[root@wtf tmp]# test -z "" && echo "true" || echo "false"true
语法格式:[ 条件测试表达式 ] ==>中括号两端要有空格
测试file文件是否存在,代码如下:
[root@wtf tmp]# [ -f file.txt ] && echo "true" || echo "false"false[root@wtf tmp]# [ -f seq.txt ] && echo "true" || echo "false"true
语法格式:[[ 条件测试表达式 ]] ==>双中括号里的两端也要有空格
常用的文件测试操作符:
用 [] 测试变量时,如果被测试的变量不加双引号,那么测试结果可能会是不正确的,如下:
[root@wtf tmp]# unset wutf[root@wtf tmp]# echo $wutf[root@wtf tmp]# [ -f $wutf ] && echo 1 || echo 0 ## $wutf是不存在的,应该返回值0,这就逻辑不对了。1[root@wtf tmp]# [ -f "$wutf" ] && echo 1 || echo 00
如果是文件实体路径,那么加引号与不加引号的结果是一样的:
[root@wtf tmp]# [ -f /etc/services ] && echo 1 || echo 01[root@wtf tmp]# [ -f "/etc/services" ] && echo 1 || echo 01
以下写法适用于所有的条件测试表达式,是工作中比较常用的替代if语句的方法。
当条件1成立时,同时执行命令1、命令2、命令3,如下:
上面的判断,相当于下面的if语句的效果,如下:
字符串测试操作符,如下:
整数二元比较操作符使用参考,如下:
针对上述符号的特殊说明⚠️:
逻辑操作符介绍如下:
对于上述操作符,说明⚠️如下几点:
#!/bin/bashFreeMem1=$(free -m|awk 'NR==2 {print $4}')FreeMem2=$(free -m|awk 'NR==2 {print $6}')FreeMem3=$(free -m|awk 'NR==2 {print $7}')# 系统剩余内存FreeMem=$(($FreeMem1+$FreeMem2+$FreeMem3))# 邮件正文内容CHARS="Current memory is $FreeMem"# 判断内存是否达到报警阀值if [ $FreeMem -lt 600 ];then # 屏幕输出显示,并写入文件 echo $FreeMem|tee /tmp/message.txt # 发送报警邮件 mail -s "$(date +%F-%T)$CHARS" 175xxxx3745@163.com < /tmp/message.txtfi
#!/bin/bash# 系统剩余内存FreeMem=$(free -m|awk 'NR==3 {print $NF}') # 等价于 $(free -m |awk 'NR==3 {print $4}')echo $FreeMem# 邮件正文内容CHARS="Current memory is $FreeMem"# 判断内存是否达到报警阀值if [ $FreeMem -lt 600 ];then # 屏幕输出显示,并写入文件 echo $FreeMem|tee /tmp/message.txt # 发送报警邮件 mail -s "$(date +%F-%T)$CHARS" 175xxxx3745@163.com < /tmp/message.txt fi
说明⚠️:
配置下系统mail,/etc/mail.rc,如下形式:
set from=175xxxx3745@163.com # 设置发件人信息,注:如果使用163邮箱,发件人信息必须设置和实际邮箱号一致,不然无法发送。set smtp=smtp.163.com # 设置邮件服务器set smtp-auth-user='175xxxx3745' # 设置验证用户名set smtp-auth-password='xxxxwtf' # 设置验证密码set smtp-auth=login # 可忽略
/etc/rsyncd.conf # rsync配置文件rsync --daemon #启动命令netstat -lnp|grep 873 #服务端口pkill rsync #停止rsync服务
说明⚠️:
# cat rsync_test.sh#!/bin/bash# 判断输入的参数个数是否为1个if [ $# -ne 1 ];then echo $"USAGE:$0 {start|stop|restart}" exit 1fi# 对输入参数行为进行判断if [ "$1" = "start" ];then rsync --daemon sleep 2 if [ $(netstat -lnp|grep rsync|wc -l) -ge 1 ];then echo "rsyncd is started" exit 0 fielif [ "$1" = "stop" ];then killall rsync &>/dev/null sleep 2 if [ $(netstat -lnp|grep rsync|wc -l) -eq 0 ];then echo "rsyncd is stopped" exit 0 fielif [ "$1" = "restart" ];then killall rsync sleep 1 killpro=$(netstat -lnp|grep rsync|wc -l) rsync --daemon startpro=$(netstat -lnp|grep rsync|wc -l) if [ $killpro -eq 0 -a $startpro -ge 1 ];then echo "rsyncd is restart" exit 0 fielse echo $"USAGE:$0 {start|stop|restart}" exit 1fi
[root@wtf tmp]# sh rsync_test.sh statusUSAGE:rsync_test.sh {start|stop|restart}[root@wtf tmp]# sh rsync_test.shUSAGE:rsync_test.sh {start|stop|restart}[root@wtf tmp]# sh rsync_test.sh stoprsyncd is stopped[root@wtf tmp]# sh rsync_test.sh startrsyncd is started[root@wtf tmp]# sh rsync_test.sh restartrsyncd is restart[root@wtf tmp]# netstat -lnp|grep 873tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 10296/rsynctcp6 0 0 :::873 :::* LISTEN 10296/rsync
# alias network="systemctl status network"# network● network.service - LSB: Bring up/down networking Loaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled) Active: active (exited) since 二 2018-10-23 11:16:46 CST; 3h 7min ago
# cat function_test1.sh#!/bin/bash# 定义一个wutf函数wutf(){ echo "this is a test function"}#调用函数wutf
# sh function_test1.shthis is a test function
首先建立函数库脚本:
# cat >>/etc/init.d/test<#!/bin/bash> test(){> echo "this company name is datagrand"> }> EOF
赋予函数库文件的执行权限:
chmod 755 /etc/init.d/test
开发执行脚本以调用上述函数:
# cat function_test2.sh#!/bin/bash[ -f /etc/init.d/test ] && source /etc/init.d/test || exit 1# 调用函数test
执行函数:
# sh function_test2.shthis company name is datagrand
定义函数库文件:# cat /etc/init.d/test2#!/bin/bashdata(){ echo "this company name is $1"}执行脚本调用上面的函数:# cat function_test3.sh#!/bin/bash[ -f /etc/init.d/test2 ] && source /etc/init.d/test2 || exit 1# 调用函数test daguan执行脚本:# sh function_test3.shthis company name is daguan
定义函数库文件:# cat /etc/init.d/test2#!/bin/bashdata(){ echo "this company name is $1"}执行脚本调用上面的函数:# cat function_test4.sh#!/bin/bash[ -f /etc/init.d/test2 ] && source /etc/init.d/test2 || exit 1# 调用函数test $1执行脚本:# sh function_test4.sh wutfthis company name is wutf
常被应用于实现系统服务启动脚本等企业应用场景中
case "变量" in 值1) 指令1 ;; 值2) 指令2 ;; *) 指令3esac
中文形象表述:
case 条件语句的执行流程逻辑图:
# cat case_test2.sh#!/bin/bash#定义颜色变量RED_COLOR='\E[1;31m'GREEN_COLOR='\E[1;32m'YELLOW_COLOR='\E[1;33m'RES='\E[0m'#定义帮助信息函数function usage(){ echo "USAGE: $0 {1|2|3|4}" exit 1}#定义菜单函数function menu(){ cat <
[root@wtf tmp]# sh case_test2.sh 1.apple 2.pear 3.bananaPlease input your choice: 1apples #红色字体[root@wtf tmp]# sh case_test2.sh 1.apple 2.pear 3.bananaPlease input your choice: 2peer #绿色字体[root@wtf tmp]# sh case_test2.sh 1.apple 2.pear 3.bananaPlease input your choice: 3banana #×××字体[root@wtf tmp]# sh case_test2.sh 1.apple 2.pear 3.bananaPlease input your choice: 4USAGE: case_test2.sh {1|2|3|4}
现在好多企业喜欢使用Svn,随着公司业务和人员的增加,运维人员需要对公司的svn平台有个比较直观的认识,如人员的增删,人员查询等。
下面的代码的作用是:一键添加、查找和查找人员信息
#!/bin/bash#create by wutf#加载系统函数库. /etc/init.d/functions#定义文件路径FILE_PATH="/tmp/passwd"[ ! -f $FILE_PATH ] && touch $FILE_PATH#定义帮助函数function usage(){ echo "USAGE: $0 {-add|-del|-search} username" exit 1}#定义判断执行账户函数function user(){ if [ $UID -ne 0 ];then echo "you are not root" exit 2 fi}#定义执行脚本参数的个数function arg_num(){ if [ $# -ne 2 ];then usage exit 3 fi}#定义case语句判断function case_info(){ case "$1" in -a|-add) shift if grep "^$1" $FILE_PATH >/dev/null 2>&1 then action "svnuser $1 is exist" /bin/false exit 4 else /bin/cp $FILE_PATH $FILE_PATH.$(date +%F%T) htpasswd $FILE_PATH $1 [ $? -eq 0 ] && action "Add $1 is success" /bin/true fi ;; -d|-del) shift if [ $(grep "$1" $FILE_PATH | wc -l) -lt 1 ];then action "svnuser $1 is not exist" /bin/false exit 5 else /bin/cp $FILE_PATH $FILE_PATH.$(date +%F%T) sed -i "/^$1/d" $FILE_PATH [ $? -eq 0 ] && action "Del $1" /bin/true || exit 6 fi ;; -s|-search) shift if [ $(grep "^$1" $FILE_PATH | wc -l) -lt 1 ];then echo "svnuser $1 is not exist" exit 7 else echo "svnuser $1 is exist" fi ;; *) exit 8 esac}#定义主函数function main(){ user arg_num $1 $2 case_info $1 $2}main $*
# sh management_svn.sh -a wutfNew password:Re-type new password:Adding password for user wutfAdd wutf is success [ 确定 ]# sh management_svn.sh -s wutfsvnuser wutf is exist# sh management_svn.sh -s wangyiwensvnuser wangyiwen is not exist# sh management_svn.sh -d wangyiwensvnuser wangyiwen is not exist [失败]# sh management_svn.sh -d wutfDel wutf [ 确定 ]
Shell脚本语言的循环语句常见的有while、until、for 和 select 循环语句。
基本语法:
while <条件表达式> do 指令。。 #注意代码缩进done 条件表达式>
说明⚠️:
while循环语句会对紧跟在while命令后的条件表达式进行判断,如果该条件表达式成立,则执行while循环体里的命令或语句(即语法中do和done之间的指令),
每一次执行到done时就会重新判断while条件表达式是否成立,直到条件表达式不成立时才会跳出while循环体。
如果一开始条件表达式就不成立,那么程序就不会进入循环体中执行命令。
可用手机充值形象说明:
while循环执行流程对应的逻辑图:
基本语法:
until <条件表达式> do 指令。。done 条件表达式>
说明⚠️:
until表达式是在条件表达式不成立时,进入循环执行指令,条件表达式成立时,终止循环。
until应用场景很罕见,了解即可。
shell中两个休息命令:
sleep 1usleep 1000000均表示休息1秒
while true #可以使用while [ 1 ] 代替do uptime sleep 2done
使用while守护进程的方式监控网站,每隔10秒确定一次网站是否正常
# cat while_test2.sh#!/bin/bash#引入系统函数库. /etc/init.d/functions#判断参数的数量if [ $# -ne 1 ];then echo "usage $0 url" exit 1fi#定义while循环while truedo if [ $(curl -o /dev/null --connect-timeout 5 -s -w "%{http_code}" $1|egrep -w "200|301|302"|wc -l) -ne 1 ];then action "this is URL $1 not normal" /bin/false else action "this is URL $1 normal" /bin/true fi sleep 10done
# sh while_test2.sh www.wutf.comthis is URL www.wutf.com normal [ 确定 ]this is URL www.wutf.com not normal [失败]this is URL www.wutf.com normal [ 确定 ]# sh while_test2.sh daguan.comthis is URL daguan.com not normal [失败]this is URL daguan.com not normal [失败]
喜欢读技术书籍,喜欢做读书笔记,以上为本人在读《跟老男孩学Linux运维之shell编程实战》这本书时的笔记,如有任何版权问题,请联系留言。
转载于:https://blog.51cto.com/wutengfei/2308998