0


[Linux][Shell][Shell逻辑控制]详细讲解

目录


1.if 判断

1.if-then

  • 语法ifcommandthencommandfi
  • bash的if语句和其他编程语言不一样,bash的if语句会直接运⾏if后⾯的命令- 如果该命令**执⾏正确(状态码为0)**,处于then的命令就会被执⾏- 否则就不会执行,或者执行其他逻辑的语句,最后到fi结束逻辑控制

2.if-then-else

  • 语法ifcommandthencommandelsecommandfi

3.elif

  • 语法
ifcommandthencommandelifcommandthencommandfi

4.case

  • 可以代替多if-else分支case"变量"in值1) 命令 ;;值2) 命令2 ;;*) 命令

5.实际上手

  • 内存监控#!/bin/bashFreeMem=`free-m|awk'NR==2 {print $NF}'`CHARS="Current memory is $FreeMem"if["$FreeMem"-lt16000]thenecho$CHARSecho"内存不足,抓紧维护服务器!"fi
  • 读取比较大小- 单分支版本#!/bin/basha=$1b=$2if[$a-lt$b]thenecho"Yes, $a less than $b"exit0fiif[$a-eq$b]thenecho"Yes, $a equal $b"exit0fiif[$a-gt$b]thenecho"Yes, $a greater than $b"exit0fi- 多分支版本#!/bin/basha=$1b=$2if[$a-lt$b]thenecho"Yes, $a less than $b"exit0elif[$a-eq$b]thenecho"Yes, $a equal $b"exit0else[$a-gt$b]echo"Yes, $a greater than $b"exit0fi
  • MySQL监控脚本#!/bin/bashif[`netstat-tunlp|grep mysql |wc-l`-ge"1"]thenecho"MySQL is running"elseecho"MySQL is stopped"# systemctl start mysql.servicefi
  • Rsync启动脚本#!/bin/bashif["$#"-ne1]thenecho"Usage: $0 {start|stop|restart}"exit1fiif["$1"="start"]then /usr/bin/rsync --daemonsleep2if[`netstat-tunlp|greprsync|wc-l`-ge1]thenecho"Rsync is started"exit0fielif["$1"="stop"]thenkillallrsync&>/dev/null sleep2if[`netstat-tunlp|greprsync|wc-l`-eq0]thenecho"Rsync is stopped"exit0fielif["$1"="restart"]thenkillrsyncsleep1killpro=`netstat-tunlp|greprsync|wc-l` /usr/bin/rsync --daemonsleep1startpro=`netstat-tunlp|greprsync|wc-l`if["$killpro"-eq0-a"$startpro"-ge1]thenecho"Rsync is restarted"exit0fielseecho"Usage: $0 {start|stop|restart}"exit1fi

2.条件测试

0.事前说明

  • 条件测试常用的语法请添加图片描述
  • 常用字符串测试操作符请添加图片描述
  • 数值比较请添加图片描述
  • 逻辑操作符请添加图片描述
  • 各命令对照表请添加图片描述

1.test 命令

  • test命令最短的定义可能是评估⼀个表达式- 如果条件为真,则返回⼀个0值- 如果表达式不为真,则返回⼀个⼤于0的值—,也可以将其称为假值- 检查最后所执⾏命令的状态的最简便⽅法是使⽤$?
  • 参数: - 关于某个文件名的类型侦测(存在与否),如:test -e filename参数意义-e该 文件名 是否存在-f该 文件名 是否为文件(file)-d该 文件名 是否为目录(directory)-b该 文件名 是否为block device装置-c该 文件名 是否为一个character device装置-S该 文件名 是否为一个Socket文件-p该 文件名 是否为一个FIFO(pile)文件-L该 文件名 是否为一个连接档- 关于文件的权限侦测,如:test -r filename参数意义-r该 文件名 是否具有可读的属性-w该 文件名 是否具有可写的属性-x该 文件名 是否具有可执行的属性-u该 文件名 是否具有SUID的属性-g该 文件名 是否具有SGID的属性-k该 文件名 是否具有Sticky bit的属性-s该 文件名 是否为非空白文件- 关于两个文件之间的比较,如:test file1 -nt file2参数意义-nt(newer than),判断file1是否比file2-ot(older than),判断file1是否比file2-ef判断file1file2是否为同⼀⽂件,可⽤在硬链接的判定上主要意义在判定,两个⽂件是否均指向同⼀个inode- 关于两个整数之间的判定,如:test num1 -eq num2参数意义-eq两数相等-ne两数不相等-gt``````num1大于num2``````-lt``````num1小于num2``````-ge``````num1大于等于num2``````-le``````num1小于等于num2- 判定字符串的数据参数意义-z为空串,则返回true``````-n不为空串,则为true``````=``````str1 == str2,则返回true``````!=``````str1 != str2,则返回true- 多重条件判断,如:test -r filename -a -x filename参数意义-a(and)两状况同时成立-o(or)两状况任何一个成立!逻辑取反

2.[]

  • 脚本中经常进行条件测试,用的最多的,就是中括号[]
  • test[]的作用是一样的
  • 基本要素:- []两个符号,左右都要有空格分隔- 内部操作符与操作变量之间要有空格,如:[ "a" = "b" ]- 字符串比较中,> <需要写成\> /<进行转义- []中字符串或者${}变量尽量使用""双引号括住,避免值未定义引用[-n"$filename"]- []中可以使用-a -o进行逻辑运算,不支持&& ||- []是bash内置命令

3.双括号

1.(())

  • bash支持双小括号,写入高级数学表达式

2.[[]]

  • 双中括号提供了针对字符串的⾼级特性,模式匹配,正则表达式的匹配
  • 基本要素- [[]]两个符号,左右都要有空格分隔- 内部操作符与操作变量之间要有空格,如:[[ "a" = "b" ]]- 字符串比较中,可以直接使用> <,无需转义- [[]]中字符串或者${}变量尽量使用""双引号括住 - 如未使用""双引号括住的话,会进行模式和元字符匹配- [[]]内部可以使用&& ||进行逻辑运算- [[]]是bash的keyword- [[]]其他用法都和[]一样

4.实际上手

  • 测试逻辑判断#!/bin/bashread-p"Pls input a char:> " var1["${var1}"-eq1]&&{echo${var1}exit0}["$var1"-eq2]&&{echo$var1exit0}["$var1"-ne"1"-a"$var1"-ne"2"]&&{echo"Script Error"exit1}
  • 模拟安装脚本#!/bin/bashpath=/scripts[!-d"$path"]&&mkdir-p scriptscat<<END 1.[install lamp] 2.[install inmp] 3.[exit]ENDread-p"Pls input your choice:> " num# 判断输入是否合法[[!$num=~[1-3]]]&&{echo"The num you input must be in {1|2|3}"echo"Input Error"exit1}[$num-eq1]&&{echo"start installing lamp...waiting..."sleep2# 如果该脚本没权限[!-x"$path/lamp.sh"]||{echo"The file does not exit or can't be exec"exit2}# 安装脚本source${path}/lamp.sh exit$?}[$num-eq2]&&{echo"start installing lnmp...waiting..."sleep2[!-x"$path/lnmp.sh"]||{echo"The file does not exit or can't be exec"exit3}source${path}/lnmp.sh exit$?}[$num-eq3]&&{echo"Bye~"exit4}

3.循环

1.for

  • 语法forvarin listdo commandsdone
  • 支持C语言风格for(( i=1;i<=10;i++))doecho"The next number is $i"done

2.while

  • 语法:此处的test commandif-else语句格式一样,可以使用任何的bash命令- 注意whiletest command的退出状态码,必须随着循环⾥的命令改变,否则状态码如果不变化,循环会不停⽌的继续下去whiletestcommanddo commandsdone
  • while命令可以写入多个测试命令- 只有最后一个测试命令的退出状态码会被决定是否退出循环- 注意换行,多个测试命令要单独的出现在每一行var1=10whileecho$var1[$var1-ge0]doecho"This is inside the loop"var1=$[$var1-1]done

3.until命令

  • untilwhile相反的语意until命令要求你指定⼀个返回⾮零退出码的测试命令- 只有退出状态码不是0,bash才会执⾏循环的命令
  • 语法untiltest commandsdo other commandsdone
  • until⽀持多个测试命令,只有最后⼀个决定bash是否执⾏其他命令untilecho$var1[$var1-eq0]doecho"Inside the loop:$var1"var1=$[$var1 - 25]done

4.控制循环

1.break

  • 作用:强制退出任意类型的循环 - 跳出多个循环时,break会自动终止所在的最内存循环
  • 终止外层循环n表示跳出的循环层级,默认是1,下一层就是2break n

2.continue

  • 作用:跳过某次循环,直接去本次循环的判断部分

5.处理循环的输出

  • 在shell脚本⾥,循环输出后的结果,可以进⾏输出重定向for(( a =1;a<10;a++))doecho"The number is $a"done> test.txtecho"Finished"
标签: linux 运维 服务器

本文转载自: https://blog.csdn.net/qq_37281656/article/details/140340863
版权归原作者 DieSnowK 所有, 如有侵权,请联系我们删除。

“[Linux][Shell][Shell逻辑控制]详细讲解”的评论:

还没有评论