bash之流程控制

作者: 多啦A梦的时光机_648d | 来源:发表于2020-02-09 21:27 被阅读0次

    一:if else

    和Java、PHP等语言不一样,sh的流程控制不可为空
    在sh/bash里可不能这么写,如果else分支没有语句执行,就不要写这个else。

    1. if

    if condition
    then
        command1 
        command2
        ...
        commandN 
    fi
    

    2. if else

    if condition
    then
        command1 
        command2
        ...
        commandN
    else
        command
    fi
    

    3. if-elif-else

    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    

    例子

    a=10
    b=20
    if [ $a == $b ]
    then
       echo "a == b"
    elif [ $a -gt $b ]
    then
       echo "a > b"
    elif [ $a -lt $b ]
    then
       echo "a < b"
    else
       echo "Ineligible"
    fi
    

    if else语句经常与test命令结合使用:(表示判断)

    1. 判断表达式

    if test  (表达式为真) 
    
    if test !表达式为假 
    
    test 表达式1 –a 表达式2                  两个表达式都为真 
    
    test 表达式1 –o 表达式2                 两个表达式有一个为真 
    

    2. 判断字符串

    test –n 字符串                                   字符串的长度非零 
    
    test –z 字符串                                    字符串的长度为零 
    
    test 字符串1=字符串2                    字符串相等 
    
    test 字符串1!=字符串2               字符串不等 
    

    3. 判断整数

    test 整数1 –eq 整数2                        整数相等 
    
    test 整数1 –ge 整数2                        整数1大于等于整数2 
    
    test 整数1 –gt 整数2                         整数1大于整数2 
    
    test 整数1 –le 整数2                         整数1小于等于整数2 
    
    test 整数1 –lt 整数2                          整数1小于整数2 
    
    test 整数1 –ne 整数2                        整数1不等于整数2
    

    4. 判断文件

    test  File1 –ef  File2                            两个文件具有同样的设备号和i结点号
    
    test  File1 –nt  File2                            文件1比文件2 新 
    
    test  File1 –ot  File2                            文件1比文件2 旧 
    
    test –b File                                           文件存在并且是块设备文件 
    
    test –c File                                           文件存在并且是字符设备文件 
    
    test –d File                                           文件存在并且是目录 
    
    test –e File                                           文件存在 
    
    test –f File                                            文件存在并且是正规文件 
    
    test –g File                                           文件存在并且是设置了组ID 
    
    test –G File                                           文件存在并且属于有效组ID 
    
    test –h File                                           文件存在并且是一个符号链接(同-L) 
    
    test –k File                                           文件存在并且设置了sticky位 
    
    test –b File                                           文件存在并且是块设备文件 
    
    test –L File                                           文件存在并且是一个符号链接(同-h) 
    
    test –o File                                           文件存在并且属于有效用户ID 
    
    test –p File                                           文件存在并且是一个命名管道 
    
    test –r File                                            文件存在并且可读 
    
    test –s File                                           文件
    
    num1=$[2*3]
    num2=$[1+5]
    if test $[num1] -eq $[num2]
    then
        echo 'Two numbers are equal!'
    else
        echo 'The two numbers are not equal!'
    fi
    

    Two numbers are equal!
    这里是shell的写法,与C的写法不一样,下面是c的写法:

    a = 10;
    if (b >= a+2)
        c = 0;
    else
        c = 1;
    

    二:for循环

    for var in item1 item2 ... itemN
    do
        command1
        command2
        ...
        commandN
    done
    

    例子

    for str in This is a string
    do
        echo $str
    done
    
    This 
    is 
    a 
    string
    

    三:while语句

    while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

    while condition
    do
        command
    done
    
    #!/bin/bash
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"
    done
    如果int小于等于5,那么条件返回真。int从1开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。
    使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
    
    #Bash let 命令变量计算中不需要加上$来表示变量
    let "int++"
    done
    #自加let int++
    #自减let int--
    # let no+=10 let no=no-20
    

    while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量MAN,按<Ctrl-D>结束循环。

    echo 'press <CTRL-D> exit'
    echo -n 'Who do you think is the most handsome: '
    while read MAN
    do
        echo "Yes!$MAN is really handsome"
    done
    

    四:无限循环

    while :
    do
        command
    done
    或者
    while true
    do
        command
    done
    

    或者

    for (( ; ; ))
    

    五:until循环

    until循环执行一系列命令直至条件为真时停止。 until循环与while循环在处理方式上刚好相反。 一般while循环优于until循环,但在某些时候—也只是极少数情况下,until循环更加有用。 until 语法格式:

    until condition
    do
        command
    done
    

    条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次—请注意这一点。

    六:case语句

    Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

    case 值 in
    模式1)
        command1
        command2
        ...
        commandN
        ;;
    模式2)
        command1
        command2
        ...
        commandN
        ;;
    esac
    
    • 取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
    • 取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
      下面的脚本提示输入1到4,与每一种模式进行匹配:
    echo 'Enter a number between 1 and 4:'
    echo 'The number you entered is:'
    read aNum
    case $aNum in
        1)  echo 'You have chosen 1'
        ;;
        2)  echo 'You have chosen 2'
        ;;
        3)  echo 'You have chosen 3'
        ;;
        4)  echo 'You have chosen 4'
        ;;
        *)  echo 'You did not enter a number between 1 and 4'
        ;;
    esac
    
    Enter a number between 1 and 4:
    The number you entered is:
    3
    You have chosen 3
    

    七:跳出循环

    在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。

    break命令

    break命令允许跳出所有循环(终止执行后面的所有循环)。 下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。

    #!/bin/bash
    while :
    do
        echo -n "Enter a number between 1 and 5:"
        read aNum
        case $aNum in
            1|2|3|4|5) echo "The number you entered is $aNum!"
            ;;
            *) echo "The number you entered is not between 1 and 5! game over!"
                break
            ;;
        esac
    done
    
    Enter a number between 1 and 5:3
    The number you entered is 3!
    Enter a number between 1 and 5:7
    The number you entered is not between 1 and 5! game over!
    

    八.continue语句

    continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 对上面的例子进行修改:

    #!/bin/bash
    while :
    do
        echo -n "Enter a number between 1 and 5: "
        read aNum
        case $aNum in
            1|2|3|4|5) echo "The number you entered is $aNum!"
            ;;
            *) echo "The number you entered is not between 1 and 5!"
                continue
                echo "game over"
            ;;
        esac
    done
    

    运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo "Game is over!" 永远不会被执行。

    九:esac

    case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break。

    判断最大值

    #!/bin/bash
    max=0
    a=8
    b=4
    c=5
    for i in $a $b $c
    do 
      if [ $i -gt $max ]
      then 
        max=$i
      fi
    done
    echo $max
    

    100以内偶数之和

    #!/bin/bash
    cnt=0
    sum=0
    for cnt in `seq 2 2 100`
    do
      sum=$((cnt+sum))
    done 
    
    echo $sum
    

    seq 2 2 100 表示列出 1 到 100 的所有偶数

    十:函数

    1.函数定义

    shell中函数的定义格式如下:

    [ function ] funname [()]
    
    {
    
        action;
    
        [return int;]
    
    }
    

    说明:

    • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
    • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)。
      下面的例子定义了一个函数并进行调用:
    #!/bin/bash
    
    demoFun(){
        echo "This is my first shell function!"
    }
    echo "-----Execution-----"
    demoFun
    echo "-----Finished-----"
    
    
    Output the result:
    -----Execution-----
    This is my first shell function!
    -----Finished-----
    

    下面定义一个带有return语句的函数:

    #!/bin/bash
    funWithReturn(){
        echo "This function will add the two numbers of the input..."
        echo "Enter the first number: "
        read aNum
        echo "Enter the second number: "
        read anotherNum
        echo "The two numbers are $aNum and $anotherNum !"
        return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "The sum of the two numbers entered is $? !"
    
    This function will add the two numbers of the input...
    Enter the first number: 
    1
    Enter the second number: 
    2
    The two numbers are 1 and  2 !
    The sum of the two numbers entered is 3 !
    

    注意:

    • 函数返回值在调用该函数后通过 $? 来获得
    • 所有函数在使用前必须定义。

    2.函数参数

    在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 n 的形式来获取参数的值,例如,n的形式来获取参数的值,例如,1表示第一个参数,$2表示第二个参数... 带参数的函数示例:

    #!/bin/bash
    funWithParam(){
        echo "The first parameter is $1 !"
        echo "The second parameter is $2 !"
        echo "The tenth parameter is $10 !"
        echo "The tenth parameter is ${10} !"
        echo "The eleventh parameter is ${11} !"
        echo "The total number of parameters is $# !"
        echo "Outputs all parameters as a string $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    
    The first parameter is 1 !
    The second parameter is 2 !
    The tenth parameter is 10 !
    The tenth parameter is 34 !
    The eleventh parameter is 73 !
    The total number of parameters is 11 !
    Outputs all parameters as a string 1 2 3 4 5 6 7 8 9 34 73 !
    

    10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数。
    注意:

    $# 是传给脚本的参数个数
    $0 是脚本本身的名字
    $1 是传递给该shell脚本的第一个参数
    $2 是传递给该shell脚本的第二个参数
    $@ 是传给脚本的所有参数的列表
    $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
    $$ 是脚本运行的当前进程ID号
    $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
    

    猜字游戏

    首先让系统随机生成一个数字,给这个数字一个范围,让用户猜数字,对输入作出判断,并且给出提示。

    请用while语句实现。

    #!/bin/bash
    
    function randNum(){
      while :
      do
        read aNum
        if test $aNum -eq $1
        then 
          echo "right"
          break 1
        else 
          if [ $aNum -gt $1 ]
            then 
               echo "The answer is smaller than yours."
             else
               echo "The answer is bigger than yours."
             fi
          fi
      done
    }
    
    randNum $(($RANDOM%100+1))
    

    相关文章

      网友评论

        本文标题:bash之流程控制

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