美文网首页
Shell结构化命令(1):控制流

Shell结构化命令(1):控制流

作者: 沐灵洛 | 来源:发表于2020-11-12 18:32 被阅读0次

    使用if - then - else语句

    if - then - else语句类似我们常用的if - else,基本格式:

    if command 
    then
    commands
    else
    commands
    fi
    

    不同于if - else的是:if - else判断条件是否成立依赖truefalse,而if - then语句依赖于ifshell command是否成功执行,即:命令的退出状态码是0

    若是0,则then后的命令被执行;若不是0,则else后的命令被执行。fi表示if - then - else语句到此结束。

    if - then - else语句也可以像if - else语句一样嵌套使用,基本格式:

    if command1 
    then
    command set 1 
    elif command2
    then
    command set 2 
    elif command3 
    then
    command set 3 
    elif command4 
    then
    command set 4
    fi
    

    使用test命令

    如果需要if - then - else语句,判断退出状态码之外的条件,如:truefalse,怎么办?解决办法,使用test命令:test condition

    关于test命令的描述:

    test用于评估表达式,如果它评估结果为true,则会返回退出状态码:0true);否则,返回退出状态码:1false);如果没有表达式,test命令也会返回退出状态码:1false)。

    testif - then - else配合:

    if test command 
    then
    commands
    else
    commands
    fi
    
    关于test的同义命令,方括号:[ ]

    基本使用格式:

    if [ condition ] then
    commands
    fi
    

    注意:第一个方括号之后和第二个方括号之前必须加上一个空格, 否则就会报错。

    布尔逻辑支持:

    [ condition1 ] && [ condition2 ] #与运算
    [ condition1 ] || [ condition2 ] #或运算
    
    关于test可以判断的三类条件:
    • 数值比较
    数值比较 描述
    n1 -eq n2 检查n1与n2是否相等
    n1 -gen2 检查n1是否大于等于n2
    n1 -le n2 检查n1是否小于等于n2
    n1 -gt n2 检查n1是否大于n2
    n1 -lt n2 检查n1是否小于n2
    n1 -ne n2 检查n1是否不等于n2
    #! /bin/bash
    # 控制流
    var1=133
    var2=145
    
    if [ $var1 -eq $var2 ] 
    then
      echo "$var1 等于 $var2"
    elif [ $var1 -ge $var2 ]
    then
      echo "$var1 大于等于 $var2"
    elif [ $var1 -le $var2 ]
    then
      echo "$var1 小于等于 $var2" #脚本输出:133 小于等于 145
    elif [ $var1 -lt $var2 ]
    then
      echo "$var1 小于 $var2"
    elif [ $var1 -gt $var2 ]
    then
      echo "$var1 大于 $var2"
    elif [ $var1 -ne $var2 ]
    then
      echo "$var1 不等于 $var2"
    else
      echo "不识别"
    fi
    
    exit 0
    

    注意,在test命令中使用浮点数会报错:145.5: integer expression expectedbash shell只能处理整数。

    • 字符串比较
    字符串比较 描述
    str1 = str2 检查str1和str2是否相等
    str1 != str2 检查str1和str2是否不相等
    str1 > str2 检查str1是否大于str2
    str1 < str2 检查str1是否小于str2
    -n str1 检查str1的长度是否非0
    -z str1 检查str1的长度是否为0
    #! /bin/bash
    # 字符串比较
    var1="abc"
    var2="acb"
    var3=""
    var4="abc"
    
    if [ -n $var1 ];then
     echo "字符串var1的长度大于0" #执行脚本输出
    fi
    
    if [ $var2 ];then
     echo "字符串var2有值"#执行脚本输出
    fi
    
    if [ -z $var3 ];then
     echo "字符串var3的长度为0"#执行脚本输出,var3未初始化也会执行
    fi
    
    if test $var4 = $var1 ; then
      echo "字符串var4=var1"#执行脚本输出
      if [ $var1 \> $var2 ]; then
       echo "字符串var1 > var2"#执行脚本输出
      elif [ $var1 != $var2 ]
      then
       echo "字符串var1不等于var2"
      else 
       echo "字符串var1小于var2"
      fi
    else
      echo "字符串var4!=var1"
    fi
    
    exit 0
    

    注意: 大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件名;大于和小于顺序和sort命令所采用的不同。

    • 文件比较
    文件比较 描述
    -d file 检查file是否存在并且是个目录
    -e file 检查file是否存在
    -f file 检查file是否存在并且是个文件
    -r file 检查file是否存在并且可读
    -w file 检查file是否存在并且可写
    -x file 检查file是否存在并且可执行
    -s file 检查file是否存在并且非空
    file1 -nt file2 检查file1是否比file2新
    file1 -ot file2 检查file1是否比file2旧
    -O file 检查file是否存在并属当前用户所有
    -G file 检查file是否存在并且默认组与当前用户相同

    示例:创建一个新的目录,新的文件,写入脚本数据,改变文件的权限,并执行该脚本。

    #! /bin/bash
    #文件比较
    var1="./compare"
    var2="wonderful"
    if [ -d $var1 ]; then
       echo "${var1}目录存在,"
       if [ -f $var1/$var2 ] && [ -s $var1/$var2 ]
       then
         echo "${var2}文件存在,并且不为空,切换工作区"
         cd ./${var1}
         if [ -x $var2 ]; then
           echo "文件存在,且可执行,内容如下:"
           cat -n $var2
           ./$var2
         else
           echo "文件存在,不可执行,写入脚本"
           ( echo "#! /bin/bash" ) > $var2
           ( echo "echo $(date) 执行 $var1/${var2}脚本成功🔥")>>$var2
           echo -n "修改权限并执行结果"
           chmod u+x $var2
           ./$var2
         fi
       else
       echo "${var2}文件不存在或文件为空"
       cd ./${var1}
          if [ -e $var2 ]; then
              echo "文件存在"
          else
              touch $var2
          fi
       echo "写入'script'到文件 $var2 "
       ( echo "#! /bin/bash" ) > $var2
       ( echo "echo $(date) 执行 $var1/${var2}脚本成功🔥")>>$var2
       echo "改变 $var2 的权限为可执行"
       chmod u+x $var2
       echo "执行${var2}脚本"
       ./${var2}
    
       fi
    else
       echo "${var1}目录不存在"
       echo "创建 $var1 目录"
       mkdir $var1
       echo "切换目录"
       cd $var1
       echo "当前工作目录:$PWD"
       echo "创建空文件:$var2"
       touch $var2
       echo "写入'script'到文件 $var2 "
       ( echo "#! /bin/bash" ) > $var2
       ( echo "echo $(date) 执行 $var1/${var2}脚本成功🔥")>>$var2
       echo "改变 $var2 的权限为可执行"
       chmod u+x $var2
       echo "执行${var2}脚本"
       ./${var2}
    fi
    

    使用if - then - else的高级特性

    • 用于数学表达式的双括号
    • 用于高级字符串处理功能的双方括号
    双括号

    双括号:允许在比较过程中使用高级数学表达式,而test只支持简单的算术比较:gtge...。

    注意:可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。

    基本格式:

    (( expression ))
    

    双括号支持的高级数学表达式:

    符号 描述
    val++、++val 后/前增
    val--、--val 后/前减
    !、&&、||、 逻辑取反、与、或
    ~、&、|、>>、<< 按位取反、与、或、右移、左移
    ** 幂运算

    示例:

    #! /bin/bash
    # 控制流
    var=5
    
    if (( $var ** 3 > 100 ));then
       echo "双括号的赋值操作:"
       var1=$var
       (( var = $var ** 3 ))
       echo -n "输出$var1 ** 3的值为: $var" #输出5 ** 3的值为: 125
       echo ""
    fi
    
    双方括号

    双方括号:该命令针对字符串比较提供的高级特性。
    基本格式:

    [[ expression ]]
    

    双方括号里的expression可使用test命令中采用的标准字符串比较,同时它还使用test命令没有的特性:模式匹配。
    模式匹配使用==,双等号右边的字符串会被视为一个模式。
    示例:

    #! /bin/bash
    # 控制流
    if [[ $USER == q* ]]
    then
    echo "Hello $USER"
    else
       echo "匹配失败"
    fi
    

    使用case命令

    case命令采用模式匹配的方式,进行变量的匹配。
    case命令的基本格式:

    case variable in
    pattern1 | pattern2) #竖线操作符在一行中分隔出多个模式
    commands1;;
    pattern3)
    commands2;;#注意必须要双分号,这是语法的一部分
    *) 
    default commands;
    esac #结束标志
    

    示例:

    #! /bin/bash
    # 控制流
    case $USER in 
    *li|*n*)
    echo "hello $USER";;
    li)
    echo "hi li";;
    *)
    echo "by";;
    esac
    

    参考资料:
    Linux命令行与shell脚本编程大全

    相关文章

      网友评论

          本文标题:Shell结构化命令(1):控制流

          本文链接:https://www.haomeiwen.com/subject/svkkvktx.html