• 使用结构化命令


      有一类名,容许脚本根据变量之的条件或者其他命令的结果跳过一些命令或者循环执行这些命令。这类命令我们通常称之为结构化命令;

    1、使用if-then语句

      语句结构为:

        if command

        then

          commands

        fi

      如果if后执行命令正确,或者返回码为0,这执行then后面的命令。如果推出状态码不是0,那么then后面的命令将不会被执行;

    #!/bin/bash
    #testing the if statement
    if date
    then
        echo "it worked"
    fi
    chmod u+x test1
    ./test1

      date命令执行成功,则状态返回值为0,所以执行then后面的命令;

      另外一个实例:

    #!/bin/bash
    #testing a bad command
    if asdfg
    then 
        echo "it didn't work"
    fi
    echo "we're outside of th if statement"
    chmod u+x test2
    ./test2

      asdfg的命令找不到,返回状态错误,则不会执行then后面的命令,直接跳到 fi 后面执行后面的echo命令。

      这里运行错误信息仍然会显示出来;

      then后面可以执行多条命令,如下面的实例:

    #!/bin/bash
    # testing multiple commands in the tehn section
    testuser=rich
    if grep $testuser /etc/passwd
    then
        echo The bash files for user $testuser are:
        ls -a /home/$testuser/.b*
    fi
    chmod u+x test3
    ./test3

      打印出teacher用户的家目录下的相关的.b*文件

      if语句也可以将then写在if的同一排,如下:

        if command; then

          commands

        fi

    2、if-then-else语句

      在if-then语句中,只能选择执行与否,而不能选择其他的命令来运行,这里我们就需要使用else;

        if command

        then

          commands

        else

          commands

        fi

      if后面的command执行成功,后面就执行then后的语句,如果返回值不是0则执行else后的语句;

    #!/bin/bash
    #testing the else section
    testuser=badtest
    if grep $testuser /etc/passwd
    then
        echo The files for user $testuser area:
        ls -a /home/$testuser/.b*
    else
        echo "The user name $testuser doesn't exist on this system"
    fi
    chmod u+x test4
    ./test4

      因为不存在badtest用户,返回值不为0,则执行else后语句;

      这样显然会更加友好

    3、嵌套的if语句

      如果选择运行的结果不止两种,则可以通过elif来实现多种选项的执行;

        if command1

        then

          commands

        elif command2

        then

          more commands

        fi

      上面的方式还是有些许的麻烦,在工作中,我们经常使用下面的方式:if-then-elif组:

        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

      命令执行,满足那个条件,则执行对应条件下的命令即可;

      但是这种使用方式依然很麻烦,而我们常用的则是case语句来实现这种需求,在后面我们会详细说道;

    4、test命令

      test命令提供了一种检测if-then语句中不同条件的方法。如果test命令中列出的条件评估值为true,test命令以0退出转态码退出,这使if-then语句使用与其他编程语句中的if-then语句一样的方法运行。如果条件为false,则test命令退出,使得if-then与语句失败;

      test用法:test condition

      关联if-then的用法:

        if test condition

        then 

          commands

        fi

      bash shell提供了一种在if-then语句中申明test命令的另外一种用法

        if [ condition ]

        then

          commnads

        fi

      [] 中定义了test的条件 condition,注意:括号里面的condition前后都必须加一个空格符;

      test支持的命令评估方式有如下三种:

        1、数值比较

        2、字符串比较

        3、文件比较

      4.1、数值比较

        例子:

    #!/bin/bash
    #using numeric test comparisons
    val1=10
    val2=11
    
    if [ $vall -gt 5 ]
    then
        echo "The test value $val1 is greater then 5"
    fi
    
    fi [ $val1 -eq $val2 ]
    then 
        echo "The values are equal"
    else
        echo "The values are different"
    fi

        第一个测试条件 $val1 -gt 5 val1的值是否大于5

        第二个测试条件 $val1 -eq $val2  val1的值是否等于val2的值

    chmod u+x test5
    ./test5

        但是test数值条件有一个限制:

    #!/bin/bash
    #testing floating point numbers
    val1=`echo "scale=4; 10 / 3" | bc`
    echo "The test value is $val1"
    if [ $val1 -gt 3 ]
    then
        echo "The result is larger than 3"
    fi
    chmod u+x test6
    ./test6

        很显然val1输出的为一个浮点数,浮点数与整数进行运算就会出错;

      4.2、字符串比较

        1、字符串相等

    #!/bin/bash
    #testing string equality
    testuser=rich
    
    if [ $USER = $testuser ]
    then
        echo "Welcome $testuser"
    fi
    chmod u+x test7
    ./test7

        $USER使用的为当前用户,与指定的变量$testuser相同,会执行后面的echo命令;

        类似的,也可以判断不相等:

    #!/bin/bash
    #testing string equality
    testuser=baduser
    
    if [ $USER != $testuser ]
    then
        echo "This isn't $testuser"
    else
        echo "Welcome $testuser"
    fi
    chmod u+x test8
    ./test8

        不相等则运行then后面的命令,如果相等,则运行else后面的命令;

        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
    chmod u+x badtest
    ./badtest

        重定向完成,没有错误,恢复状态码0,则运行then后面的命令;

        我们需要通过转意字符  来解决这个问题;

    #!/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
    chmod u+x test9
    ./test9

        字符串的大小写的比较

    #!/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
    chmod u+x test10
    ./test10

        说明:小写字母要比大小字母大。

        3、字符串的大小

        评估一个变量是否包含数据的时候,通过-n和-z来比较就比较方便了

    #!/bin/bash
    #testing string length
    val1=testing
    val2=''
    
    if [ -n $val1 ]  #val1的长度是否为非0
    then
        echo "The string '$val1' is not empty"
    else
        echo "The string '$val1' is empty"
    fi
    
    if [ -z $val2 ]  #val2的长度是否为0
    then
        echo "The string '$val2' is empty"
    else
        echo "The string '$val2' is not empty"
    fi
    
    if [ -z $val3 ]  #没有定义$val3,所以它的长度也是0
    then
        echo "The string '$val3' is empty"
    else
        echo "The string '$val3' is not empty"
    fi
    chmod u+x test10
    ./test10

      4.3、文件比较

        这是在我们脚本中最长使用的一类比较:

        1、检查目录

        -d 检测指定的文件是否存在于我们的系统中。

    #!/bin/bash
    #look before you leap
    if [ -d $HOME ]
    then 
        echo "Your HOME directory exists"
        cd $HOME
        ls -a
    else
        echo "There's a problem with your HOME directory"
    fi

        判断用户的home目录是否存在;

        2、查找对象是否存在

        -e 比较能够检查文件或者目录是否存在;

    #!/bin/bash
    #checking if a directory exists
    if [ -e $HOME ]  #检查是否存在家目录
    then
        echo "OK on the directory, now let's check the file"
        #Checking if a file exists
        if [ -e $HOME/testing ]  #检查家目录下的testing目录是否存在
        then
            #the file exists, append data to it 
            echo "Appending date to existing file"
            date >> $HOME/testing  #存在则追加数据
        else
            #the file doesn't exist,create a new file
            echo "Creating new file"
            date > $HOME/testing  #不存在则直接重定向数据到这个文件中即可
        fi
    else
        echo "Sorry,you don't have a HOME directory"
    fi

        3、检查文件

        -f 用来进行比较

    #!/bin/bash
    #check if a file
    if [ -e $HOME ]  #判断家目录是否存在
    then
        echo "The object exists, is it a file?"
        if [ -f $HOME ]  #如果存在,则判断他是否是一个文件
        then
            echo "Yes, it's a file!"
        else
            echo "No, it's not a file!"
            if [ -f $HOME/.bash_history ]  #判断$HOME/.bash_history是否为文件
            then
                echo "But this is a file!"
            fi
        fi
    else
        echo "Sorroy,the object doesn't exist"
    fi

        4、是否能读

        -r 判断文件是否具有刻度权限

    #!/bin/bash
    #testing if you can read a file
    pwfile=/etc/shadow
    
    #first ,test is the file exists,and is a file
    if [ -f $pwfile ]
    then
        #now test if you can read it 
        if [ -r $pwfile ]
        then
            tail $pwfile
        else
            echo "Sorry,I'm unable to read the $pwfile file"
        fi
    else
        echo "Sorry,the file $pwfile doesn't exist"
    fi

        5、检查空文件

        -s比较文件是否为空

    #!/bin/bash
    #testing if a file is empty
    file=t15test
    touch $file
    
    if [ -e $file ]
    then
        echo "The $file file exists and has data in it"
    else
        echo "The $file exists and is empty"
    fi
    
    date > $file
    if [ -s $file ]  #判断$file问价那种是否存在数据
    then 
        echo "The $file file has data in it"
    else
        echo "The $file is still empty"
    fi

        6、检查是否能够向文件中写入数据

        -w 比较确定是否有权限向文件中写入数据

    #!/bin/bash
    #checking if a file is writeable
    
    logfile=$HOME/t16test
    touch $logfile
    chmod u-w $logfile
    now=`date +%Y%m%d-%H%M`
    
    if [ -w $logfile ]  #判断$logfile是否有写权限
    then
        echo "The program ran at: $now" > $logfile
        echo "The fist attempt succeeded"
    else
        echo "The first attempt failed"
    fi
    
    chmod u+w $logfile
    if [ -w $logfile ]
    then 
        echo "The program ran at: $now" > $logfile
        echo "The second attempt succeeded"
    else
        echo "The second attempt failed"
    fi

        7、检查是否能够运行文件

        -x 判断文件是否具有执行权限

    #!/bin/bash
    #testing file execution
    if [ -x test16 ]  #判断test16文件是否具有执行权限
    then
        echo "You can run the script:"
        ./test16
    else
        echo "Sorry,you are unable to execute the script"
    fi

        8、检查所有权

        -O 比较可以容易的检查您是否是问价你的所有者

    #!/bin/bash
    #check file ownsership
    if [ -O /etc/passwd ]
    then
        echo "You're the ower of the /etc/passwd file"
    else
        echo "Sorry,you're not the owner of th /etc/passwd file"
    fi

        第一次在普通用户下检查则失败,之后切换到root用户下,就能成功;

        -G 检查文件的默认组,匹配默认组匹配成功,就正确;

    #!/bin/bash
    #check file group test
    
    if [ -G $HOME/testing ]  #判断
    then
        echo "You're in the same group as the file"
    else
        echo "The file is not owned by your group"
    fi
    ./test19
    chgrp sharing $HOME/testing
    ./test19

        9、检查文件日期

        -nt 比较确定一个文件是否比另一个文件新

        -ot 比较确定一个文件是否比另一个文件更旧

    #!/bin/bash
    #testing file dates
    
    if [ ./test19 -nt ./test18]
    then
        echo "The test19 file is newer than test18"
    else
        echo "The test18 file is newer than test19"
    fi
    
    if [ ./test17 -ot ./test19 ]
    then
        echo "The test17 file is older than the test19 file"
    fi

        如果正在检查的文件可以四处移动,则这个脚本就会出现问题,另一个问题是,这两个比较都不能用于检查文件是否一开始就存在。

    #!/bin/bash
    #testing file dates
    
    if [ ./badfile1 -nt ./badfile2 ]
    then
        echo "The badfile1 file is newer than badfile2"
    else
        echo "The badfile2 file is newer than badfile1"
    fi

        文件在不存在的时候,比较依然继续进行;

    5、复合条件查找

      if-then语句可以使用布尔逻辑啦进行复合条件查找:

      [ condition1 ] && [ condition2 ]  #这个是and

      [ condition2 ] || [ condition2 ]  #这个是or

    #!/bin/bash
    #testing compound comparisons
    
    if [ -d $HOME ] && [ -w $HOME/testing ]
    then
        echo "The file exists and you can write to it "
    else 
        echo "I can't write to the file"
    fi

    6、if-then的高级特征

      bash shell中最近新增加了两个比较新的功能,他们提供了可以在if-then语句中使用的高级功能:

      *双圆括号表示数学表达式

      *双方括号表示高级字符串处理函数

      6.1、使用双圆括号

        (( expression ))

        可以在if语句中使用双圆括号名,也可以使用普欧婷命令再脚本中进行赋值:

    #!/bin/bash
    #using double parenthesis
    
    val1=10
    
    if (( $val1 ** 2 > 90 ))
    then 
        (( val2 = $val1 ** 2 ))
        echo "The sequare of $val1 is $val2"
    fi

        在双圆括号中不必进行符号转意;

      6.2、使用双方括号

        [[ expression ]]  #模式匹配(pattern)

        在模式匹配中,可以定义字符串相匹配的正则表达式

    #!/bin/bash
    #using pattern matching
    if [[ $USER == r* ]]
    then
        echo "Hello $USER"
    else
        echo "Sorroy,I don't know you"
    if

    7、case命令

      if-then-else,选项多了以后,会比较麻烦,代码执行效率会比较低;

      所以我们可以使用case语句来实现;

    #!/bin/bash
    #looking for a possible value
    
    if [ $USER = "rich" ]
    then
        echo "Welcome $USER"
        echo "Please enjoy your visit"
    elif [ $USER = barbara ]
    then
        echo "Welcome $USER"
        echo "Please enjoy your visit"
    elif [ $USER = testing ]
    then
        echo "Special testing account"
    elif [ $USER = jessica ]
    then
        echo "Don't forget to logout when you're done"
    else
        echo "Sorry,you're not allowed here"
    fi

      这样的代码运行效率比较低,每个选项都会进行比较

      case语句来实现这个功能;

        case variable in

        pattern1 | pattern2) commands1;;

        pattern3) commands2;;

        *) default commands;;

        esac

    #!/bin/bash
    #using the case command
    
    case $USER in
    rich | barbara)
        echo "Welcome,$USER"
        echo "Please enjoy your visit";;
    testing)
        echo "Special testing account";;
    jessica)
        echo "Don't forget to log off when you're done";;
    *)
        echo "Sorry,you're not allowed here";;
    esac
  • 相关阅读:
    正则表达式与领域特定语言(DSL)
    css兼容性问题的整理
    ASP.NET Web API 2.0新特性:Attribute Routing1
    架构讨论
    用Jekyll在github上写博客
    日历插件(beta)
    SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面)
    Maven中有三大模块
    hdu 2444
    4.4 从一个表向另外的表中复制行
  • 原文地址:https://www.cnblogs.com/BurnovBlog/p/10783240.html
Copyright © 2020-2023  润新知