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


1.if 判断

1.if-then

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

2.if-then-else

  • 语法
    if command
    then
    	command
    else
    	command
    fi
    

3.elif

  • 语法
if command
then
	command
elif command
then
	command
fi

4.case

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

5.实际上手

  • 内存监控
    #!/bin/bash
    
    FreeMem=`free -m | awk 'NR==2 {print $NF}'`
    CHARS="Current memory is $FreeMem"
    
    if [ "$FreeMem" -lt 16000 ]
    then
        echo $CHARS
        echo "内存不足,抓紧维护服务器!"
    fi
    
  • 读取比较大小
    • 单分支版本
      #!/bin/bash
      
      a=$1
      b=$2
      
      if [ $a -lt $b ]
      then
          echo "Yes, $a less than $b"
          exit 0
      fi
      
      if [ $a -eq $b ]
      then
          echo "Yes, $a equal $b"
          exit 0
      fi
      
      if [ $a -gt $b ]
      then
          echo "Yes, $a greater than $b"
          exit 0
      fi
      
    • 多分支版本
      #!/bin/bash
      
      a=$1
      b=$2
      
      if [ $a -lt $b ]
      then
          echo "Yes, $a less than $b"
          exit 0
      elif [ $a -eq $b ]
      then
          echo "Yes, $a equal $b"
          exit 0
      else [ $a -gt $b ]
          echo "Yes, $a greater than $b"
          exit 0
      fi
      
  • MySQL监控脚本
    #!/bin/bash
    
    if [ `netstat -tunlp | grep mysql | wc -l` -ge "1" ]
    then
        echo "MySQL is running"
    else
        echo "MySQL is stopped"
        # systemctl start mysql.service
    fi
    
  • Rsync启动脚本
    #!/bin/bash
    
    if [ "$#" -ne 1 ]
    then
        echo "Usage: $0 {start|stop|restart}"
        exit 1
    fi
    
    if [ "$1" = "start" ]
    then
        /usr/bin/rsync --daemon
        sleep 2
    
        if [ `netstat -tunlp | grep rsync | wc -l` -ge 1 ]
        then
            echo "Rsync is started"
            exit 0
        fi
    elif [ "$1" = "stop" ]
    then
        killall rsync &>/dev/null
        sleep 2
    
        if [ `netstat -tunlp | grep rsync | wc -l` -eq 0 ]
        then
            echo "Rsync is stopped"
            exit 0
        fi
    elif [ "$1" = "restart" ]
    then
        kill rsync
        sleep 1
    
        killpro=`netstat -tunlp | grep rsync | wc -l`
        /usr/bin/rsync --daemon
        sleep 1
    
        startpro=`netstat -tunlp | grep rsync | wc -l`
    
        if [ "$killpro" -eq 0 -a "$startpro" -ge 1 ]
        then
            echo "Rsync is restarted"
            exit 0
        fi
    else
        echo "Usage: $0 {start|stop|restart}"
        exit 1
    fi
    

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两数不相等
      -gtnum1大于num2
      -ltnum1小于num2
      -genum1大于等于num2
      -lenum1小于等于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.(())

2.[[]]

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

4.实际上手

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

3.循环

1.for

  • 语法
    for var in list
    do
    	commands
    done
    
  • 支持C语言风格
    for (( i=1;i<=10;i++ ))
    do
    	echo "The next number is $i"
    done
    

2.while

  • 语法:此处的test commandif-else语句格式一样,可以使用任何的bash命令

    • 注意whiletest command的退出状态码,必须随着循环⾥的命令改变,否则状态码如果不变化,循环会不停⽌的继续下去
      while test command
      do
      	commands
      done
      
  • while命令可以写入多个测试命令

    • 只有最后一个测试命令的退出状态码会被决定是否退出循环
    • 注意换行,多个测试命令要单独的出现在每一行
      var1=10
      while echo $var1
      	[ $var1 -ge 0 ]
      do
      	echo "This is inside the loop"
      	var1=$[ $var1 -1 ]
      done
      

3.until命令

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

4.控制循环

1.break

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

2.continue

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

5.处理循环的输出

  • 在shell脚本⾥,循环输出后的结果,可以进⾏输出重定向
    for (( a = 1;a<10;a++ ))
    do
    	echo "The number is $a"
    done > test.txt
    echo "Finished"
    
  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值