美文网首页Lunix学习
第二十四课 LinuxShell编程二之使用结构化命令

第二十四课 LinuxShell编程二之使用结构化命令

作者: Arroganter | 来源:发表于2018-09-05 16:06 被阅读10次

    说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第十二章学习总结

    第十二章:使用结构化命令
    本章内容

    使用if-then语句
    嵌套if语句
    test命令
    复合条件测试
    使用双方括号和双括号
    case命令
    

    12.1 使用if-then语句
    语句格式:

    if command
    then
    command
    fi
    

    if command; then
    command
    fi
    

    语句说明:bash shell的if语句会运行if后面的那个命令,如果该命令的退出状态码是0(该命令执行成功),则位于then部分的命令就回被执行。如果不是0,则不执行then部分的命令,继续执行脚本中的下一个命令。fi语句表示if-then语句到此结束。

    编写test1.sh脚本

    #!/bin/bash
    # testing the if statement
    if pwd
    then
        echo It worked
    fi
    

    编写test2.sh脚本

    #!/bin/bash
    # testing a bad command
    if IamNotaCommand
    then 
        echo "It worked"
    fi
    echo "We are outside the if statement"
    

    编写test3.sh脚本

    #!/bin/bash
    if grep $testuser /etc/passwd
    then 
        echo "This is my first command"
        echo "This is my second command" 
        echo "I can even put in other commands besides echo:"
        ls -a /home/$testuser/.b*
    fi
    

    12.2 if-then-else语句
    语句格式

    if command
    then 
    command
    else
    command
    fi
    

    语句说明:当if语句中的命令返回退出状态码为0时,then部分中的命令会被执行;当状态码不为0时,else部分中的命令会被执行。

    编写test4.sh脚本

    #!/bin/bash
    # testing multiple commands in the then section
    
    testuser=nosuchuser
    
    if grep $testuser /etc/passwd
    then 
        echo "This is my first command"
        echo "This is my second command" 
        echo "I can even put in other commands besides echo:"
        ls -a /home/$testuser/.b*
    else
        echo "The user $testuser does not exist on this system."
    fi
    

    12.3 嵌套if
    要检查/etc/passwd文件中是否存在某个用户以及该用户的目录是否尚在,可以使用嵌套的if-then语句。嵌套的if-then语句位于主if-then-else语句的else代码块中。

    语句格式

    if command1
    then
    commands
    elif command2
    then
    more commands
    else
    moreandmore commands
    fi
    

    语句说明:先执行command1,返回状态码为0时,执行commands,从elif到fi之间的命令则跳过。当command1返回状态码不为0时,则执行command2,command2的返回状态码为0,则执行more commands;不为0,则执行moreandmore commands。

    编写test5.sh脚本

    #!/bin/bash
    # testing nested ifs - use elif
    
    testuser=nosuchuser
    
    if grep $testuser /etc/passwd
    then
        echo "The user $testuser exists on this system."
    elif ls -d /home/$testuser
    then
        echo "The user $testuser dose not exist on this system."
        echo "However,$testuser has a directory"
    else
        echo "The user $testuser dose not exist on this system."
        echo "And,$testuser dose not have a directory"
    fi
    

    窍门:在elif语句中,紧跟其后的else语句属于elif代码块。它们并不属于之前的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 5
    fi
    

    12.4 test命令
    命令格式:test condition
    命令说明:如果test命令中列出的条件成立,test命令就回返回0,否则返回非零的状态码,这样就可以结合if-then语句使用。

    语句格式

    if test condition
    then
    commands
    fi
    

    语句说明:如果test命令的condition部分为空时,它会返回非零的退出状态码。

    语句格式

    if [ condition ]
    then
    commands
    fi
    

    语句说明:bash shell提供的另一种测试方法,第一个方括号之后和第二个方括号之前必须加一个空格。

    test命令可以判断三类条件

    数值比较
    字符串比较
    文件比较
    12.4.1 数值比较
    test命令的数值比较功能

    n1 -eq n2:检查n1是否等于n2
    n1 -gen2:检查n1是否大于或等于n2
    n1 -gt n2:检查n1是否大于n2
    n1 -le n2:检查n1是否小于或等于n2
    n1 -lt n2:检查n1是否小于n2
    n1 -ne n2:检查n1是否不等于n2
    

    编写numberic_test.sh脚本

    #!/bin/bash
    value1=10
    value2=11
    #
    if [ $value1 -gt 5 ]
    then
        echo "The test value $value1 is greater then 5"
    fi
    #
    if [ $value1 -eq $value2 ]
    then
        echo "The values are equal"
    else
        echo "The values are different"
    fi
    

    bash shell只能处理整数。如果只是通过echo来显示浮点数,则没问题;如果用于数值比较,则会出错。

    编写floating_point_test.sh脚本

    #!/bin/bash
    #
    value1=5.555
    #
    echo "The test value is $value1"
    #
    if [ $value1 -gt 5 ]
    then
        echo "The test value $value1 is greater then 5"
    fi
    

    12.4.2 字符串比较
    字符串比较测试

    str1 = str2:检查str1是否和str2相同
    str1 != str2:检查str1是否和str2不同
    str1 < str2:检查str1是否比str2小(使用时大于符号注意转义)
    str1 > str2:检查str1是否比str2大(使用时小于符号注意转义)
    -n str2:检查str1的长度是否非0
    -z str2:检查str1的长度是否为0
    

    1.字符串相等性

    编写test7.sh脚本

    #!/bin/bash
    # testing string equality
    testuser=rich
    #
    if [ $USER = $testuser ]
    then
        echo "Welcome $testuser"
    else
        echo "This is not $testuser"
    fi
    

    编写test8.sh脚本

    #!/bin/bash
    # testing string equality
    testuser=rich
    #
    if [ $USER != $testuser ]
    then
        echo "This is not $testuser" 
    else
        echo "Welcome $testuser"  
    fi
    

    2.字符串顺序

    编写test9.sh脚本

    #!/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
    

    注意:在进行字符串比较时,使用的是标准的ASCII顺序,根据每个字符的ASCII数值来决定排序结果,大写字母被认为是小于小写字母的。但sort命令恰好相反。

    说明:test命令和测试表达式使用标准的数学比较符号来表示字符串比较,而用文本代码(如:-eq,-ge等)来表示数值比较。这个细微的特性被很多程序员理解反了。如果你对数值使用了数据运算符,shell会将它们当成字符串值,可能无法得到正确的结果。

    3.字符串大小

    编写test10.sh脚本

    #!/bin/bash
    # testing string length
    val1=testing
    val2=''
    #
    if [ -n $val1 ]
    then
        echo "The string '$val1' is not empty" 
    else
        echo "The string '$val1' is empty"
    fi
    #
    if [ -z $val2 ] 
    then
        echo "The string '$val2' is empty"
    else
        echo "The string '$val2' is not empty"
    fi
    #
    if [ -z $val3 ] 
    then
        echo "The string '$val3' is empty"
    else
        echo "The string '$val3' is not empty"
    fi
    

    敲门:空的和未初始化的变量会对shell脚本测试造成灾难性的影响。如果不是很确定一个变量的内容,最好在将其用于数值或字符串比较之前先通过-n或-z来测试一下变量是否含有值。

    12.4.3 文件比较
    test命令的文件比较功能

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

    1.检查目录

    -d测试会检查指定的目录是否存在于系统中。如果你打算将文件写入目录或是准备切换到某个目录中,先进行测试总是件好事情

    编写test11.sh脚本

    #!/bin/bash
    # Look before you leap
    #
    jump_directory=/home/zc
    #
    if [ -d $jump_directory ]
    then
        echo "The $jump_directory directory exists"
        cd $jump_directory
        ls
    else
        echo "The $jump_directory directory dose not exist"
    fi
    

    2.检查对象是否存在

    -e比较允许你的脚本代码在使用文件或目录前先检查它们是否存在

    编写test12.sh脚本

    #!/bin/bash
    # Check if either a directory or file exists
    #
    location=$HOME
    file_name="sentinel"
    #
    if [ -e $location ]
    then #Directory does exist
        echo "OK on the $location directory."
        echo "Now checking on the file, $file_name."
        #
        if [ -e $location/$file_name ]
        then #File does exist
            echo "OK on the filename"
            echo "Updating Current Date..."
            date >> $location/$file_name
        #
        else #File does not exist
            echo "File does not exist"
            echo "Nothing to update"
        fi
    #
    else #Directory does not exist
        echo "The $location directory does not exist."
        echo "Nothing to update"
    fi
    

    3.检查文件

    -e比较可用于文件和目录。要确定指定对象为文件,必须用-f比较

    编写test12.sh

    #!/bin/bash
    # check if either a directory or file exists
    #
    item_name=$HOME
    echo
    echo "The item being checked: $item_name"
    echo
    #
    if [ -e $item_name ]
    then #Item does exist
        echo "The item, $item_name, does exist."
        echo "But is it a file?"
        echo
        #
        if [ -f $item_name ]
        then #Item is a file
            echo "Yes, $item_name is a file."
        #
        else #Item is not a file
            echo "No, $item_name is not a file."
        fi
    #
    else #Item does not exist
        echo "The item, $item_name, does not exist."
        echo "Nothing to update"
    fi
    

    4.检查是否可读

    在尝试从文件中读取数据之前,最好先测试一下文件是否可读,可以使用-r比较测试

    编写test14.sh脚本

    #!/bin/bash
    # testing if you can read a file
    pwfile=/etc/shadow
    #
    # first, test if 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 am unable to read the $pwfile file"
        fi
    else
        echo "Sorry, the file $pwfile does not exist"
    fi
    

    5.检查空文件

    使用-s比较来检查文件是否为空,当-s比较成功时,说明文件中有数据。

    编写test15.sh脚本

    #!/bin/bash
    # Testing if a file is empty
    #
    file_name=$HOME/sentinel
    #
    if [ -f $file_name ]
    then
        if [-s $file_name ]
        then
            echo "The $file_name file exists and has data in it."
            echo "Will not remove this file."
        else
            echo "The $file_name file exists,but is empty."
            echo "Deleting empty file..."
            rm $file_name
        fi
    else
        echo "File,$file_name,does not exist."
    fi
    

    6.检查是否可写

    使用-w比较进行判断你对文件是否有可写权限

    编写test16.sh脚本

    #!/bin/bash
    # check if a file is writable.
    #
    item_name=$HOME/sentinel
    echo
    echo "The item being checked: $item_name"
    echo
    #
    if [ -e $item_name ]
    then #Item does exist
        echo "The item, $item_name, does exist."
        echo "But is it a file?"
        echo
        #
        if [ -f $item_name ]
        then #Item is a file
            echo "Yes, $item_name is a file."
            echo "But is it writable?"
            echo
            #
            if [ -w $item_name ]
            then #Item is writable
                echo "Writing current time to $item_name"
                date +$H$M >> $item_name
            #
            else #Item is not writable
                echo "Unable to write to $item_name"
            fi
        #
        else #Item is not a file
            echo "No, $item_name is not a file."
        fi
    #
    else #Item does not exist
        echo "The item, $item_name, does not exist."
        echo "Nothing to update"
    fi
    

    7.检查文件是否可以执行

    使用-x比较判断特定文件是否有执行权限

    编写test17.sh脚本

    #!/bin/bash
    # testing file execution
    #
    if [ -x test16.sh ]
    then 
        echo "You can run the script:"
        ./test16.sh
    else
        echo "Sorry, you are unable to execute the script"
    fi
    

    8.检查所属关系

    使用-O比较测试当前用户是否是文件的属主

    编写test18.sh脚本

    #!/bin/bash
    # eheck file ownership
    #
    if [ -O /etc/passwd ]
    then 
        echo "You are the owner of the /etc/passwd file"
    else
        echo "Sorry, you are not the owner of the /etc/passwd file"
    fi
    

    9.检查默认属组关系

    使用-G比较检查文件的默认组,如果它匹配了用户的默认组,则测试成功。注:-G比较只会检查默认组而非用户所属的所有组。

    编写test19.sh脚本

    #!/bin/bash
    # check file group test
    #
    if [ -G $HOME/testing ]
    then
        echo "You are in the same group as the file"
    else
        echo  "The file is not owned by you group"
    fi
    

    10.检查文件日期

    使用-nt比较判断一个文件是否比另一个文件新。如果文件较新,则文件的创建日期更近。
    使用-ot比较判断一个文件是否比另一个文件旧。如果文件较旧,则文件的创建日期更早。

    编写test20.sh脚本

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

    编写test21.sh脚本

    #!/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
    

    注意:这些命令都没有检查文件是否存在,在使用这些命令之前,必须先确认文件是存在的

    12.5 复合条件测试
    if-then语句允许使用布尔逻辑来组合测试,格式如下

    [ condition1 ] && [ condition2 ]
    [ condition1 ] || [ condition2 ]
    

    窍门:布尔逻辑是一种能够将可能的返回值简化为TRUE或FALSE的方法

    编写test22.sh脚本

    #!/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 connot write to the file"
    fi
    

    12.6 if-then的高级特性
    12.6.1 使用双括号
    命令格式:(( expression ))
    命令说明:使用双括号可以在比较过程中使用高级数据表达式
    双括号命令符号

    val++:后自增
    val--:后自减
    ++val:先自增
    --val:先自减
    !:逻辑求反
    ~:位求反
    **:幂运算
    <<:左位移
    >>:右位移
    &:位布尔与
    |:位布尔或
    &&:逻辑与
    ||:逻辑或
    

    编写test23.sh脚本

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

    12.6.2 使用双方括号
    命令格式:[[ expression ]]
    命令说明:在单方括号的基础上,增加了模式匹配
    命令注意:并不是所有的shell都支持双方括号
    编写test24.sh脚本

    #!/bin/bash
    # using pattern matching
    #
    if [[ $USER == z* ]]
    then
        echo "Hello $USER"
    else
        echo "Sorry,I do not know you"
    fi
    12.7 case命令
    编写test25.sh脚本
    
    #!/bin/bash
    # looking for a possible value
    #
    if [ $USER = "zc" ]
    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 "Do not forget to logout when you're done"
    else
        echo "Sorry, you are not allowd here"
    fi
    

    命令格式:

          case variable in
          pattern1 | pattern2) commands1;;
          pattern3) commands2;;
          *) commands3;;
          esac
    

    命令说明:case命令会将指定的变量与不同模式进行比较

    编写test26.sh脚本

    #!/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 "Do not forget to log off when you're done";;
    *)
    echo "Sorry, you are not allowed here";;
    esac
    

    12.8 小结
    结构化命令可以改变shell脚本的正常执行流。最基本的结构化命令是if-then语句。该语句可以根据一个执行一个命令的结果来执行其他命令。本章介绍了if-then、if-then-else、elif、case语句。

    相关文章

      网友评论

        本文标题:第二十四课 LinuxShell编程二之使用结构化命令

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