第11章 使用结构化命令

      许多程序要求在shell脚本中的命令间有一些逻辑控制流。

      有一类命令会基于变量 值或其他命令的结果等条件使脚本跳过或循环执行命令。这样的命令通常称为结构化命令。

使用if-then语句

      结构化命令中,最基本的类型就是if-then语句。格式如下:

      if  command

      then

           command

      fi

     与其他编程语言不同,bash shell的if语句会会运行if行定义的那个命令。如果该命令的退出状态码是0(该命令运行成功),位于then部分的命令就会被执行。反之,如果该命令的推出状态码是其他的值,那then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令。

   if-then语句还有其他的一种格式:

        if command:then

           commands

        fi


if-then-else语句

      在if-then语句中,不管命令是否成功执行,都只有一种选择。为解决这个问题,可以使用if-then-else语句。

      格式:

            if  command

            then

                commands

            else 

                commands

            fi

      当if语句中的命令返回退出状态码0时,then部分中的命令会被执行,跟普通的if-then一样。当返回非零退出状态码时,bash shell会执行else部分中的命令。

      跟then部分一样。else部分可以包含多条命令。

嵌套if

     有时需要检查脚本代码中的多种条件。不用写多个分立的fi-then语句,可以用else部分的替代版本,称作elif。 elif会通过另一个if-then语句来延续else部分:

    if comamand1

    then

       commands

    elif command2

    then 

        more commands

     fi

     elif语句提供了另一个要测试的命令,类似于原始的if语句。如果elif后命令的推出状态码是0,则bash会执行第二个then语句部分的命令。

     还可以继续使用多个elif语句串起来,形成一个大的if-thenelif嵌套组合:

     if command1

     then

          command  set 1

     elif command2

     then

          command set 2

     elif command3

     then

           command set 3

     elfi command4

     then

          command set 4

     fi

     每块命令都会根据哪个命令会返回退出状态码0来执行。bash shell 会依次执行if语句,只有第一个返回推出状态码0的语句中的then部分会被执行。这部分可由case命令代替。


tets命令

   if-then语句是否能测试跟命令的退出状态码无关的条件。答案是不能。但是,bash shell中有个好用的工具可以帮助你通过if-then语句测试其他条件。
      test命令提供了在if-then语句中测试不同条件的路径。如果test命令中列出的条件成立,test就会退并返回推出状态码0.这样if-then语句就与其他编程语言中的if-then语句以类似的方式工作了。如果条件不成立,test命令就会推出并返回推出状态码1,这样if-then语句就会失效。
     test命令格式
    test  condition
   当test用在if-then语句中时,用法如下:
    if test condition
    then
       commands
   fi
   bash shell 还提供了另一种在if-then语句中声明test命令的方法:
   if 【 condition 】
   then
      commands
   fi
   方括号定义了test命令中用到的条件,注意:必须在方括号的左侧与右侧各加一个空格,否则会报错。
   test命令会判断3类条件:
   数值比较
   字符串比较
   文件比较

数值比较 (可以用在数字和变量上)
    最常见的情形是对两个数值进行比较。如下表
                    比较                                                                                    描述
            n1 -eq n2                                                                          检查n1是否与n2相等
            n1 -ge n2                                                                          检查n1是否大于或等于n2
            n1 -gt  n2                                                                          检查n1是否大于n2
            n1 -le  n2                                                                          检查n1是否小于等于n2
            n1 -lt   n2                                                                          检查n1是否小于n2
            n1 -ne n2                                                                         检查n1是否不等于n2
    
        bash shell能处理的数仅有整数。当使用bash计算器时,可以让shell将浮点值作为字符串值存储进一个变量。test命令不能使用浮点值。


 字符串比较

     test命令还允许比较字符串值。但比较繁琐,如下表:

                   比较                                                                        描述

            str1 = str2                                                               检查str1是否和str2相同

            str1 != str2                                                           检查str1是否和str2不同

            str1  <   str2                                                            检查str1是否比str2小

            str1  >   str2                                                            检查str1是否比str2大

            -n  str1                                                                    检查str1的长度是否非0

           -z    str1                                                                   检查str1的长度是否为0

       字符串的相等性

        比较字符串的相等性时,test的比较会将所有的标点和大写也考虑在内。

      字符串顺序

        要测试一个字符串是否比另一个字符串大就变得繁琐了。有两个问题会经常困扰:

             1、大于小于符号必须转义,都则shell会把它们当作重定向符号而把字符串值当作文件名

             2、大于小于顺序和sort命令所采用的不同

        在编写脚本时,第一条肯呢个会导致一个不易察觉的严重问题。一个简单的例子:

       #! /bin/bash

       # mis-using string comparisons

      val1=baseball

      val2=hockey

      if [ $val1 > $val2 ]

      then

        echo "$val1 is greater than $val2"

      else

       echo "$val1 is less than $val2"

      fi

      这里只用了大于号,没有出现错误,但结果是错的。脚本把大于号解释成了输出重定向。因此,创建了一个名为hockey的文件。由于重定向顺利完成了,test命令返回了推出状态码0,而if语句则以为所有的命令都成功结束了。

     要解决这个问题。只需要正确的转义大于号。

    # mis-using string comparisons

      val1=baseball

      val2=hockey

      if [ $val1 \> $val2 ]

      then

        echo "$val1 is greater than $val2"

      else

       echo "$val1 is less than $val2"

      fi

    第二个问题更加细微,除非你经常处理大小写字母,否则几乎遇不到。sort命令处理大写字母的方法刚好跟test命令相反。测试如下脚本:

     #!/bin/bash
# testing string sort order

val1=Testing
val2=testing

if [ $val1 \> $val2 ]
then
  echo "$val1 is greater than $val2"
else
  echo "$val1 is less than $val2"
fi

¥sort testfile

  testing

 Testing

   在test命令中,大写字母会被当成小于小写字母的。但当你将同样的字符串放进文件中,并用sort命令排序时,小写字母会先出现。这是由于各个命令所使用的排序技术不同造成的。test命令会使用标准的ASCII顺序,sort命令使用系统的本地化语言设置中定义的排序顺序。对于英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前。

 

字符串大小

     -n和-z来检查一个变量是否含有数据。

文件比较

     最后一类测试比较可能是shell变成中最强大的也是最经常用到的比较。test命令允许你测试Linux文件系统上文件和目录的状态。如下表:

                          比较                                                                                       描述

                     -d file                                                                                  检查file是否存在并是一个目录

                    -e file                                                                                   检查file是否存在

                     -f file                                                                                  检查file是否存在并是一个文件


   检查目录

    -d file测试会检查指定文件名是否在系统上以目录形式存在。

   检查对象是否存在

    -e file比较允许你在脚本中使用对象前检查文件或目录对象是否存在。

  检查文件

    -e比较适合于文件和目录。要确定指定的对象是个文件,你必须用-f比较。

   检查是否可读

    在尝试从文件中读取数据之前,最好先测试一下能否读文件。可以通过-r比较测试。

  检查空文件

    -s可以用来检查文件 是否为空,尤其是删除文件时,当-s比较成功时,要特别小心。

  检查是否可写

   -w比较会判断你是否对文件有可写权限

  检查是否可执行

   -x比较是一个简便的判断你对某个特定文件是否有执行的权限。虽然大多数命令永不到它,但在shell中运行大量脚本时会很方便。

  检查所属关系

   -o比较允许你轻松地测试你是否是文件的属主

   检查默认属主关系

   -G比较会检查文件的默认组,如果它匹配了用户的默认组,那就通过了。但-G只会检查默认组而非用户所属的所有其他组(默认即是groups显示出的第一个组)。

   检查文件日期

   -nt比较会判定某个文件是否比另一个文件更新。如果问家更新,它会有一个比较近的文件创建日期。-ot会判定某个文件是否比另一个文件更老。如果文件更老,它会有一个更早的创建日期。这在编写安装软件的脚本时非常有用。因为你不想安装一个较老的文件。


复合条件测试

    if-then语句允许你使用bool逻辑来组合测试。如下

    1、 [  condition1  ]  && [  condition2  ];

    2、 [  condition1  ]  ||  [  conditoon2  [.


if-then的高级特性

   使用双尖括号

        test命令只允许你在比较中进行简单的算数操作。双尖括号允许将高级数学表达式放入比较中。格式如下:

       (( expression ))

      术语expression可以是任意的数字赋值或比较表达式。下表为双尖括号命令符:

                         符号                                                                   描述

                     val++                                                                  后增

                     val- -                                                                   后减

                     ++val                                                                  先增

                     - -val                                                                   先减

                     !                                                                        逻辑求反

                       ~                                                                      位求反

                        **                                                                      幂运算

                       <<                                                                     左位移 

                        >>                                                                     右位移

                        &                                                                        位布尔和

                        |                                                                         位布尔或

                        &&                                                                    逻辑和

                         ||                                                                      逻辑或

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

使用双方括号

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

       [[ expression ]]

        expression使用了test命令中采用的标准字符串进行比较。但它提供了test命令未提供的一个特性----模式匹配。

       在模式匹配中。可以定义一个正则表达式来匹配字符串值。


case命令

       解决值多时用多个elif来判定。case命令会检查单个变量列表格式的多个值:

      case variable in

      pattern1 | pattern2) command1;; (连续两个分号)

      pattern3) command2;;

      *) default commands;;

      esac

      case命令会将指定的变量同不同模式进行比较。若变量和模式是匹配的,那么shell会执行为该模式指定的命令。可以通过竖线操作符来分割模式。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值