美文网首页
Shell基础

Shell基础

作者: TomyZhang | 来源:发表于2020-09-04 16:46 被阅读0次

    一、构建基本脚本

    1.创建shell脚本文件

    在创建shell脚本文件时,必须在文件的第一行指定要使用的shell,其格式为:

    #!/bin/bash
    

    在通常的shell脚本中,井号(#)用作注释行,shell并不会处理shell脚本中的注释行。然而,shell脚本文件的第一行是个例外,#后面的惊叹号会告诉shell用哪个shell来运行脚本:

    #!/bin/bash
    # This script displays the date
    date
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    2020年 09月 03日 星期四 23:37:55 CST
    

    2.显示消息

    使用echo命令显示字符串:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo hello shell
    hello shell
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo "It's shell"
    It's shell
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo 'It says "shell"'
    It says "shell"
    

    可以将echo语句添加到shell脚本中任何需要显示额外信息的地方:

    #!/bin/bash
    # This script displays the date
    echo "The time and date are:"
    date
    echo "end"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The time and date are:
    2020年 09月 03日 星期四 23:47:43 CST
    end
    

    如果想把文本字符串和命令输出显示在同一行中,可以用echo语句的-n参数:

    #!/bin/bash
    # This script displays the date
    echo -n "The time and date are:"
    date
    echo "end"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The time and date are:2020年 09月 04日 星期五 00:07:34 CST
    end
    

    3.使用变量

    环境变量

    shell维护着一组环境变量,用来记录特定的系统信息。比如系统的名称、登录到系统上的用户名、用户的系统ID(也称为UID)、用户的默认主目录以及shell查找程序的搜索路径。可以用set命令来显示一份完整的当前环境变量列表。在脚本中,你可以在环境变量名称之前加上美元符($)来使用这些环境变量:

    #!/bin/bash
    echo "User info for userid: $USER"
    echo UID: $UID
    echo HOME: $HOME
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    User info for userid: zhangwenming
    UID: 1009
    HOME: /home/zhangwenming
    

    要显示美元符,必须在它前面放置一个反斜线:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo This cost \$99
    This cost $99
    

    用户变量

    除了环境变量,shell脚本还允许在脚本中定义和使用自己的变量。定义变量允许临时存储数据并在整个脚本中使用,从而使shell脚本看起来更像一个真正的计算机程序。与系统变量类似,用户变量可通过美元符引用:

    #!/bin/bash
    days=10
    guest="shell"
    echo "$guest checked in $days days ago"
    days=5
    guest="python"
    echo "$guest checked in $days days ago"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    shell checked in 10 days ago
    python checked in 5 days ago
    

    命令替换

    shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量,有两种方法:

    • 反引号字符(`)
    • $( )格式
    #!/bin/bash
    testing1=`date`
    testing2=$(date +%y%m%d)
    echo "$testing1"
    echo "$testing2"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    2020年 09月 04日 星期五 00:54:43 CST
    200904
    

    4.重定向输入和输出

    输出重定向

    最基本的重定向将命令的输出发送到一个文件中。bash shell用大于号(>)来完成这项功能:

    #!/bin/bash
    testing1=`date`
    testing2=$(date +%y%m%d)
    echo "$testing1"
    echo "$testing2"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test > output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    2020年 09月 04日 星期五 02:10:53 CST
    200904
    

    有时你可能并不想覆盖文件原有内容,而是想要将命令的输出追加到已有文件中,可以用双大于号(>>)来追加数据:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test >> output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    2020年 09月 04日 星期五 02:12:35 CST
    200904
    2020年 09月 04日 星期五 02:13:46 CST
    200904
    

    输入重定向

    输入重定向符号是小于号(<):

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    2020年 09月 04日 星期五 02:12:35 CST
    200904
    2020年 09月 04日 星期五 02:13:46 CST
    200904
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ wc < output
      4  14 100
    

    wc命令可以对数据中的文本进行计数。默认情况下,它会输出3个值:

    • 文本的行数
    • 文本的词数
    • 文本的字节数

    5.管道

    管道被放在命令之间,将一个命令的输出重定向到另一个命令中:

    command1 | command2
    

    Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output | wc
          4      14     100
    

    6.执行数学运算

    expr命令

    expr命令允许在命令行上处理数学表达式,但是特别笨拙:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ expr 5 + 7
    12
    

    在shell脚本中使用expr命令:

    #!/bin/bash
    var1=10
    var2=20
    var3=$(expr $var2 / $var1)
    echo The result is $var3
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The result is 2
    

    使用方括号

    在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号( $[ operation ] )将数学表达式围起来:

    #!/bin/bash
    var1=10
    var2=20
    var3=$[($var2 / $var1) * 10]
    echo The result is $var3
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The result is 20
    

    浮点解决方案

    bash计算器实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    5 * 1.2
    6.0
    

    在脚本中使用bc,基本格式如下:

    variable=$(echo "options; expression" | bc)
    
    #!/bin/bash
    var1=$(echo "scale=4; 3.44 / 5" | bc)
    echo The result is $var1
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The result is .6880
    

    7.退出脚本

    查看退出状态码

    Linux提供了一个专门的变量$?来保存上个已执行命令的退出状态码:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date
    2020年 09月 04日 星期五 04:06:55 CST
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo $?
    0
    

    exit命令

    默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。exit命令允许你在脚本结束时指定一个退出状态码:

    #!/bin/bash
    var1=$(echo "scale=4; 3.44 / 5" | bc)
    echo The result is $var1
    exit 99
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    The result is .6880
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo $?
    99
    

    二、使用结构化命令

    1.使用if-then语句

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

    if command
    then 
        commands
    fi
    

    在其他编程语言中,if语句之后的对象是一个等式,这个等式的求值结果为TRUE或FALSE。但bash shell的if语句并不是这么做的。bash shell的if语句会运行if后面的那个命令,如果该命令的退出状态码是0(该命令成功运行),位于then部分的命令就会被执行。如果该命令的退出状态码是其他值,then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令:

    #!/bin/bash
    if pwd
    then
        echo "It worked"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    /home/zhangwenming/workspace/Tomorrow
    It worked
    

    2.if-then-else语句

    if command
    then 
        commands
    else
        commands
    fi
    

    3.嵌套if

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

    4.test命令

    test命令提供了在if-then语句中测试不同条件的途径。如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0,这样if-then语句就与其他编程语言中的if-then语句以类似的方式工作了。如果条件不成立,test命令就会退出并返回非零的退出状态码,这使得if-then语句不会再被执行。test命令的格式非常简单:

    test condition
    

    condition是test命令要测试的一系列参数和值。当用在if-then语句中时,test命令看起来是这样的:

    if test condition
    then
        commands
    fi
    

    如果不写test命令的condition部分,它会以非零的退出状态码退出,并执行else语句块:

    #!/bin/bash
    if test
    then
        echo "It excute then"
    else
        echo "It excute else"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    It excute else
    

    可以使用test命令确定变量中是否有内容:

    #!/bin/bash
    variable="Full"
    if test variable
    then
        echo "It excute then"
    else
        echo "It excute else"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    It excute then
    

    bash shell提供了另一种条件测试方法,无需在if-then语句中声明test命令:

    if [ condition ]
    then
        commands
    fi
    

    方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

    test命令可以判断三类条件:

    • 数值比较
    • 字符串比较
    • 文件比较

    数值比较

    比较 描述
    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
    #!/bin/bash
    var1=10
    var2=20
    if [ $var1 -gt $var2 ]
    then
        echo ">"
    else
        echo "<="
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./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
    #!/bin/bash
    var1=hello
    var2=world
    if [ $var1 \> $var2 ]
    then
        echo ">"
    else
        echo "<="
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
    <=
    

    文件比较

    文件比较是shell编程中最为强大、也是用得最多的比较形式,它允许你测试Linux文件系统上文件和目录的状态。

    比较 描述
    -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旧
    #!/bin/bash
    var=/home/zhangwenming
    if [ -d $var ]
    then
        echo "directory"
    else
        echo "not directory"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    directory
    

    5.复合测试条件

    if-then语句允许你使用布尔逻辑来组合测试,有两种布尔运算符可用:

    • [ condition1 ] && [ condition2 ]
    • [ condition1 ] || [ condition2 ]
    #!/bin/bash
    var=/home/zhangwenming
    
    if [ -d $var ] && [ -w $var ]
    then
        echo "directory can write"
    else
        echo "not directory or can not write"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    directory can write
    

    6.if-then的高级特性

    使用双括号

    双括号命令的格式如下:

    (( expression ))
    

    expression可用是任意的数学赋值或比较表达式。除了test命令使用的标准数学运算符,还会用到其他运算符:

    符号 描述
    val++ 后增
    val-- 后减
    ++val 先增
    --val 先减
    ! 逻辑求反
    ~ 位求反
    ** 幂运算
    << 左位移
    >> 右位移
    & 位布尔和
    | 位布尔或
    && 逻辑和
    || 逻辑或
    #!/bin/bash
    var1=10
    
    if (( $var1 ** 2 > 90 ))
    then
        (( var2 = var1 ** 2 ))
        echo "result is: $var2"
    else
        (( var2 = var1 * 2 ))
        echo "result is: $var2"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    result is: 100
    

    注意,不需要将双括号中表达式里大于号转义。这是双括号命令提供的另一个高级特性。

    使用双方括号

    双方括号命令的格式如下:

    [[ expression ]]
    

    双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命令未提供的另一个特性——模式匹配。在模式匹配中,可以定义一个正则表达式来匹配字符串值:

    #!/bin/bash
    if [[ $USER == zhang* ]]
    then
        echo "hello $USER"
    else
        echo "Sorry, I do not know you"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    hello zhangwenming
    

    7.case命令

    case命令采用列表格式来检查单个变量的多个值:

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

    case命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么shell会执行为该模式指定的命令:

    #!/bin/bash
    case $USER in
    li*)
      echo "Welcome, li";;
    huang* | zhang*)
      echo "Welcome, huang or zhang";;
    *)
      echo "Sorry, you are not allowed here";;
    esac
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Welcome, huang or zhang
    

    三、更多的结构化命令

    1.for命令

    bash shell中for命令的基本格式:

    for var in list
    do 
        commands
    done
    

    读取列表中的值:

    #!/bin/bash
    for test in Android Java Kotin Python 
    do
      echo "current is: $test"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: Android
    current is: Java
    current is: Kotin
    current is: Python
    

    读取列表中的复杂值:

    #!/bin/bash
    for test in I don\'t know if "this'll" work
    do
      echo "current is: $test"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: I
    current is: don't
    current is: know
    current is: if
    current is: this'll
    current is: work
    

    从变量读取列表:

    #!/bin/bash
    list="Android Java Kotin Python"
    for test in $list "Shell"
    do
      echo "current is: $test"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: Android
    current is: Java
    current is: Kotin
    current is: Python
    current is: Shell
    

    从命令读取值:

    #!/bin/bash
    file="output"
    for test in $(cat $file)
    do
      echo "current is: $test"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: 123
    current is: 456
    current is: abc
    

    更改字段分隔符:

    默认情况下,bash shell会将下列字符当做字段分隔符:

    • 空格
    • 制表符
    • 换行符

    如果bash shell在数据中看到了这些字符中的任意一个,它就会假定这表明了列表中一个新数据字段的开始。可以在shell脚本中临时更改IFS环境变量的值来限制被bash shell当作字段分隔符的字符。例如,修改IFS的值,使其只能识别换行符:

    #!/bin/bash
    file="output"
    IFS=$'\n'
    for test in $(cat $file)
    do
      echo "current is: $test"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: 123 456
    current is: abc
    

    如果要指定多个IFS字符,只要将它们在赋值行串起来就行:

    IFS=$'\n':;" 
    

    这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。

    用通配符读取目录:

    #!/bin/bash
    file="output"
    IFS=$'\n'
    for file in /home/zhangwenming/workspace/Tomorrow/NEW_ZWM/*
    do
        if [ -d "$file" ]
        then
          echo "$file is a directory"
        elif [ -f "$file" ]
        then
          echo "$file is a file"
        fi  
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    /home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test_one is a file
    /home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test_two is a file
    /home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test.txt is a file
    

    在Linux中,目录名和文件名中包含空格当然是合法的。要适应这种情况,应该将$file变量用双引号圈起来。

    2.C语言风格的for命令

    #!/bin/bash
    for (( a=1, b=10; a<=10; a++, b--))
    do
        echo "$a - $b"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    1 - 10
    2 - 9
    3 - 8
    4 - 7
    5 - 6
    6 - 5
    7 - 4
    8 - 3
    9 - 2
    10 - 1
    

    3.while命令

    while的基本格式

    while test command
    do
        other commands
    done
    

    while命令中定义的test command和if-then语句中的格式一模一样。可以使用任何普通的bash shell命令,或者用任何普通的bash shell命令,或者用test命令进行条件测试,比如测试变量值:

    #!/bin/bash
    var1=5
    while [ $var1 -gt 0 ]
    do
        echo $var1
        var1=$[ $var1 - 1 ]
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    5
    4
    3
    2
    1
    

    使用多个测试命令

    while命令允许你在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环:

    #!/bin/bash
    var1=5
    while echo $var1
          [ $var1 -gt 0 ]
    do
        echo "This is inside the loop"
        var1=$[ $var1 - 1 ]
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    5
    This is inside the loop
    4
    This is inside the loop
    3
    This is inside the loop
    2
    This is inside the loop
    1
    This is inside the loop
    0
    

    4.until命令

    until命令要求你指定一个通常返回非零退出状态码的测试命令。只有测试命令的退出状态码不为0,bash shell才会执行循环中列出的命令。一旦测试命令返回了退出状态码0,循环就结束。until命令的格式如下:

    until test command
    do 
        other commands
    done
    
    #!/bin/bash
    var1=5
    until [ $var1 -le 0 ]
    do
        echo "current is: $var1"
        var1=$[ $var1 - 1 ]
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is: 5
    current is: 4
    current is: 3
    current is: 2
    current is: 1
    

    和while命令类似,你可以在until命令语句中放入多个测试条件,只有最后一个命令的退出状态码决定了bash shell是否执行已定义的other commands:

    #!/bin/bash
    var1=5
    until echo $var1
          [ $var1 -le 0 ]
    do
        echo "inside the loop"
        var1=$[ $var1 - 1 ]
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    5
    inside the loop
    4
    inside the loop
    3
    inside the loop
    2
    inside the loop
    1
    inside the loop
    0
    

    5.嵌套循环

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "start loop $a:"
        for (( b=1; b<=3; b++ ))
        do
            echo "  inside the loop $b"
        done
    done 
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    start loop 1:
      inside the loop 1
      inside the loop 2
      inside the loop 3
    start loop 2:
      inside the loop 1
      inside the loop 2
      inside the loop 3
    start loop 3:
      inside the loop 1
      inside the loop 2
      inside the loop 3
    

    6.循环处理文件数据

    #!/bin/bash
    IFS=$'\n'
    for entry in $(cat output)
    do
        echo "value is $entry"
    done
    
    abczhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    value is 123 456
    value is abc
    

    7.控制循环

    break命令

    跳出单个循环:

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "current is $a"
        if [ $a -eq 2 ]
        then
            break
        fi
    done 
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    current is 1
    current is 2
    

    跳出内部循环:

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "start loop $a:"
        for (( b=1; b<=3; b++ ))
        do
            echo "  inside the loop $b"
            if [ $b -eq 2 ]
            then
                break
            fi
        done
    done 
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    start loop 1:
      inside the loop 1
      inside the loop 2
    start loop 2:
      inside the loop 1
      inside the loop 2
    start loop 3:
      inside the loop 1
      inside the loop 2
    

    跳出外部循环:

    break命令接受单个命令行参数值:break n,其中n指定了要跳出的循环层级,n为1表明跳出的是当前的循环,n为2表明会停止下一级的外部循环:

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "start loop $a:"
        for (( b=1; b<=3; b++ ))
        do
            echo "  inside the loop $b"
            if [ $b -eq 2 ]
            then
                break 2
            fi
        done
    done 
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    start loop 1:
      inside the loop 1
      inside the loop 2
    

    continue命令

    continue命令可以提前中止某次循环中的命令,但并不会完全终止整个循环:

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "start loop $a:"
        for (( b=1; b<=3; b++ ))
        do
            if [ $b -eq 2 ]
            then
                continue
            fi
            echo "  inside the loop $b"
        done
    done 
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    start loop 1:
      inside the loop 1
      inside the loop 3
    start loop 2:
      inside the loop 1
      inside the loop 3
    start loop 3:
      inside the loop 1
      inside the loop 3
    

    8.处理循环的输出

    在shell脚本中,你可以对循环的输出使用管道或进行重定向,这可以通过在done命令之后添加一个处理命令来实现:

    #!/bin/bash
    for (( a=1; a<=3; a++ ))
    do
        echo "start loop $a:"
        for (( b=1; b<=3; b++ ))
        do
            if [ $b -eq 2 ]
            then
                continue
            fi
            echo "  inside the loop $b"
        done
    done > output
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    start loop 1:
      inside the loop 1
      inside the loop 3
    start loop 2:
      inside the loop 1
      inside the loop 3
    start loop 3:
      inside the loop 1
      inside the loop 3
    

    四、处理用户输入

    1.命令行参数

    向shell脚本传递数据的最基本方法是使用命令行参数。命令行参数允许在运行脚本时向命令行添加数据。bash shell会将一些称为位置参数的特殊变量分配给输入到命令行中的所有参数,这也包括shell所执行的脚本名称。位置参数是标准的数字:0是程序名,1是第一个参数,$2是第二个参数,以此类推。

    #!/bin/bash
    echo "position 0: $0"
    echo "position 1: $1"
    echo "position 2: $2"
    echo "position 3: $3"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell perfect
    position 0: ./test.sh
    position 1: hello
    position 2: shell
    position 3: perfect
    

    在使用参数前一定要检查其中是否存在数据:

    #!/bin/bash
    echo "position 0: $0"
    echo "position 1: $1"
    echo "position 2: $2"
    if [ -n "$s2" ]
    then
      echo "position 3: $3"
    else
      echo "position 3 no value"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
    position 0: ./test.sh
    position 1: hello
    position 2: shell
    position 3 no value
    

    2.特殊参数变量

    参数统计

    特殊变量$#含有脚本运行时携带的命令行参数的个数,可以在脚本中任何地方使用这个特殊变量,就跟普通变量一样:

    #!/bin/bash
    echo "position 0: $0"
    echo "position 1: $1"
    echo "position 2: $2"
    if [ -n "$s2" ]
    then
      echo "position 3: $3"
    else
      echo "position 3 no value"
    fi
    echo "total param count: $#"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
    position 0: ./test.sh
    position 1: hello
    position 2: shell
    position 3 no value
    total param count: 2
    

    抓取所有的数据

    *和@变量可以用来轻松访问所有参数,这个两个变量包含了命令行中出现的每一参数值。

    *变量会将命令行上提供的所有参数当做一个单词保存。@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词,这样你就能够遍历所有的参数值,得到每一个参数,通常通过for命令完成。

    #!/bin/bash
    for param in "$*"
    do
        echo "* is: $param"
    done
    for param in "$@"
    do
        echo "@ is: $param"
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
    * is: hello shell
    @ is: hello
    @ is: shell
    

    3.获得用户输入

    基本的读取

    read命令从标准输入(键盘)或另一个文件描述符中接受输入。在收到输入后,read命令会将数据放进一个变量:

    #!/bin/bash
    echo -n "Enter you name: "
    read name
    echo "Hello $name, welcome to my program."
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Enter you name: Tomy
    Hello Tomy, welcome to my program.
    

    read命令包含了-p选项,允许你直接在read命令行指定提示符:

    #!/bin/bash
    read -p "Please enter your age: " age
    days=$[ $age * 365 ]
    echo "That makes you over $days days old"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Please enter your age: 10
    That makes you over 3650 days old
    

    使用多个变量:

    #!/bin/bash
    read -p "Please enter your name and age: " name age
    days=$[ $age * 365 ]
    echo "$name, you over $days days old"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Please enter your name and age: Android 11
    Android, you over 4015 days old
    

    超时

    可以用-t选项来指定一个计时器,-t选项指定了read命令等待输入的秒数。当计时器过期后,read命令会返回一个非零退出状态码:

    #!/bin/bash
    if read -t 5 -p "Please enter your name and age: " name age
    then
        days=$[ $age * 365 ]
        echo "$name, you over $days days old"
    else
        echo
        echo "Sorry, too slow"
    fi
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Please enter your name and age:
    Sorry, too slow
    

    也可以不对输入过程计时,而是让read命令来统计输入的字符数,当输入的字符达到预设的字符数时,就自动退出,将输入的数据赋给变量:

    #!/bin/bash
    read -n1 -p "Do you want to continue [Y/N]? " answer
    case $answer in
    Y | y) echo
           echo "fine, continue on...";;
    N | n) echo
           echo "OK, goodbye"
           exit;;
    esac
    echo "script end"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Do you want to continue [Y/N]? n
    OK, goodbye
    

    隐藏方式读取

    -s选项可以避免在read命令中输入的数据出现在显示器上(实际上,数据会被显示,只是read命令会将文本颜色设成跟背景色一样):

    #!/bin/bash
    read -s -p "Enter you password: " pass
    echo
    echo "your password is: $pass"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Enter you password:
    your password is: tomorrow
    

    从文件中读取

    也可以用read命令来读取Linux系统上文件里保存的数据。每次调用read命令,它都会从文件中读取一行文本。当文件中在没有内容时,read命令会退出并返回非零退出状态码:

    #!/bin/bash
    count=1
    cat output | while read line
    do 
        echo "Line $count: $line"
        count=$[$count + 1]
    done
    echo "read file done"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Line 1: start loop 1:
    Line 2: inside the loop 1
    Line 3: inside the loop 3
    Line 4: start loop 2:
    Line 5: inside the loop 1
    Line 6: inside the loop 3
    Line 7: start loop 3:
    Line 8: inside the loop 1
    Line 9: inside the loop 3
    read file done
    

    五、呈现数据

    1.理解输入和输出

    标准文件描述符

    Linux系统将每个对象当作文件处理。这包括输入和输出进程。Linux用文件描述符(file descriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次最多可以有几个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0、1和2):

    文件描述符 缩写 描述
    0 STDIN 标准输入
    1 STDOUT 标准输出
    2 STDERR 标准错误

    STDIN文件描述符代表shell的标准输入。对终端界面来说,标准输入是键盘。shell从STDIN文件描述符对应的键盘获得输入,在用户输入时处理每个字符。在使用输入重定向符号(<)时,Linux会用重定向指定的文件来替换标准输入文件描述符。它会读取文件并提取数据,就如同它是键盘上键入的。

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat
    Hello shell
    Hello shell
    ^C
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat < output
    start loop 1:
      inside the loop 1
      inside the loop 3
    start loop 2:
      inside the loop 1
      inside the loop 3
    start loop 3:
      inside the loop 1
      inside the loop 3
    

    STDOUT文件描述符代表shell的标准输出。在终端界面上,标准输出就是终端显示器。shell的所有输出(包括shell中运行的程序和脚本)会被定向到标准输出中,也就是显示器。通过输出重定向符号,通常会显示到显示器的所有输出会被shell重定向到指定的重定向文件。你也可以将数据追加到某个文件,这可以用>>符号来完成。

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date
    2020年 09月 04日 星期五 21:32:27 CST
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date >> output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    start loop 1:
      inside the loop 1
      inside the loop 3
    start loop 2:
      inside the loop 1
      inside the loop 3
    start loop 3:
      inside the loop 1
      inside the loop 3
    2020年 09月 04日 星期五 21:32:47 CST
    

    shell通过特殊的STDERR文件描述符来处理错误消息。STDERR文件描述符代表shell的标准错误输出。shell或shell中运行的程序和脚本出错时生成的错误消息都会发送到这个位置。默认情况下,STDERR文件描述符会和STDOUT文件描述符指向同样的地方(尽管分配给它们的文件描述符值不同)。也就是说,默认情况下,错误消息也会输出到显示器输出中。

    重定向错误

    只重定向错误:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al badfile 2> output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    ls: cannot access badfile: No such file or directory
    

    重定向错误和数据:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al newfile badfile 2> errout 1> output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
    ls: cannot access badfile: No such file or directory
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    -rw-rw-r-- 1 zhangwenming zhangwenming 0  9月  3 23:02 newfile
    

    将STDERR和STDOUT的输出重定向到同一个输出文件:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al newfile badfile &> output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    ls: cannot access badfile: No such file or directory
    -rw-rw-r-- 1 zhangwenming zhangwenming 0  9月  3 23:02 newfile
    

    2.在脚本中重定向输出

    临时重定向

    可以将单独的一行输出重定向到STDERR:

    #!/bin/bash
    echo "This is error output" >&2
    echo "This is normal output"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh 2> errout
    This is normal output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
    This is error output
    

    永久重定向

    可以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符:

    #!/bin/bash
    exec 2> errout
    echo "hello shell"
    exec 1>output
    echo "this is normal output"
    echo "this is err output" >&2
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    hello shell
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
    this is normal output
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
    this is err output
    

    3.在脚本中重定向输入

    exec命令允许你将STDIN重定向到Linux系统上的文件中:

    #!/bin/bash
    exec 0< output
    count=1
    while read line
    do
        echo "Line #$count: $line"
        count=$[ $count + 1 ]
    done
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Line #1: 123 456
    Line #2: abc
    

    六、控制脚本

    1.处理信号

    Linux利用信号与运行在系统中的进程进行通信。

    生成信号

    中断进程:CTRL+C组合键会发送SIGINT信号,停止shell中当前运行的进程。

    暂停进程:CTRL+Z组合键会生成一个SIGTSTP信号,停止shell中运行的任何进程。

    停止进程跟终止进程不同:停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行。

    捕获信号

    trap命令允许你来指定shell脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交由本地处理。trap命令的格式是:

    trap commands signals
    
    #!/bin/bash
    trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
    sleep 10
    echo "end of the script"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    ^C Sorry! I have trapped Ctrl-C
    end of the script
    

    捕获脚本退出

    #!/bin/bash
    trap "echo Goodbye..." EXIT
    sleep 10
    echo "end of script"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    end of script
    Goodbye...
    

    2.以后台模式运行脚本

    后台运行脚本

    #!/bin/bash
    trap "echo Goodbye..." EXIT
    sleep 10
    echo "end of script"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
    [1] 114907
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
    F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
    0 S  1009 114907 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
    0 S  1009 114908 114907  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
    0 R  1009 114909 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
    Goodbye...
    
    [1]+  Done                    ./test.sh
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
    F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
    0 R  1009 114911 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
    

    运行多个后台作业

    #!/bin/bash
    trap "echo Goodbye..." EXIT
    sleep 10
    echo "end of script"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
    [1] 114919
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
    [2] 114921
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
    F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
    0 S  1009 114919 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
    0 S  1009 114920 114919  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
    0 S  1009 114921 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
    0 S  1009 114922 114921  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
    0 R  1009 114924 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
    Goodbye...
    end of script
    Goodbye...
    
    [1]-  Done                    ./test.sh
    [2]+  Done                    ./test.sh
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
    F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
    0 R  1009 114925 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
    

    3.作业控制

    查看作业

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
    [1] 114941
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ jobs -l
    [1]+ 114941 Running                 ./test.sh &
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ kill 114941
    Goodbye...
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ jobs -l
    [1]+ 114941 Terminated              ./test.sh
    

    重启停止的作业

    要以后台模式重启一个作业,可用bg命令加上作业号:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    ^Z
    [1]+  Stopped                 ./test.sh
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ bg 1
    [1]+ ./test.sh &
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
    Goodbye...
    
    [1]+  Done                    ./test.sh
    

    要以前台模式重启作业,可用带有作业号的fg命令:

    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    ^Z
    [1]+  Stopped                 ./test.sh
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ fg 1
    ./test.sh
    end of script
    Goodbye...
    

    七、创建函数

    1.基本的脚本函数

    创建函数

    有两种格式可用用来在bash shell脚本中创建函数。第一种格式采用关键字function,后跟分配给该代码块的函数名:

    function name {
        commands
    }
    

    第二种格式更接近于其他编程语言中定义函数的方式:

    name() {
    commands
    }
    

    使用函数

    #!/bin/bash
    
    function func1 {
      echo "This is an example of a function"
    }
    
    echo "call function start"
    func1
    func1
    echo "call function end"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    call function start
    This is an example of a function
    This is an example of a function
    call function end
    

    2.返回值

    默认退出状态码

    默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码:

    #!/bin/bash
    
    function func1 {
      echo "This is an example of a function"
    }
    
    echo "call function start"
    func1
    echo "The exit status is: $?"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    call function start
    This is an example of a function
    The exit status is: 0
    

    使用return命令

    bash shell使用return命令来退出函数并返回特定的退出状态码。return命令允许指定一个整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设定函数的特定退出状态码:

    #!/bin/bash
    
    function func1 {
      echo "This is an example of a function"
      return 99
    }
    
    echo "call function start"
    func1
    echo "The exit status is: $?"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    call function start
    This is an example of a function
    The exit status is: 99
    

    使用函数输出

    获取任何类型的函数输出,并将其保存到变量中:

    #!/bin/bash
    
    function func1 {
      echo "This is an example of a function"
    }
    
    result=$(func1)
    echo "The exit status is: $result"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    The exit status is: This is an example of a function
    

    3.在函数中使用变量

    向函数传递参数

    #!/bin/bash
    
    function func1 {
      echo "param1 is $1"
      echo "param2 is $2"
    }
    
    func1 hello shell
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    param1 is hello
    param2 is shell
    

    在函数中处理变量

    全局变量:默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可以函数内正常访问。

    #!/bin/bash
    
    function func1 {
      value=$[ $value * 2 ]
    }
    
    value=99
    func1
    echo "result is: $value"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    result is: 198
    

    局部变量:函数内部使用的任何变量都可以被声明成局部变量。

    #!/bin/bash
    
    function func1 {
      local temp=$[ $value * 2 ]
      value=$[ $temp + 100 ]
    }
    
    value=99
    func1
    echo "result is: $value"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    result is: 298
    

    4.数组变量和函数

    向函数传递数组参数

    #!/bin/bash
    
    function func1 {
      local sum=0
      local newarray
      newarray=($(echo "$@"))
      for value in ${newarray[*]}
      do
        sum=$[ $sum + $value ]
      done
        echo $sum
    }
    
    myarray=(1 2 3 4 5)
    echo "The original array is: ${myarray[*]}"
    arg1=$(echo ${myarray[*]})
    result=$(func1 $arg1)
    echo "result is: $result"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    The original array is: 1 2 3 4 5
    result is: 15
    

    从函数返回数组

    #!/bin/bash
    
    function func1 {
      local newarray
      newarray=($(echo "$@"))
      elements=$[ $# - 1 ]
      for (( i=0; i<=$elements; i++ ))
      {
        newarray[$i]=$[ ${newarray[$i]} * 2 ]
      }
      echo ${newarray[*]}
    }
    
    myarray=(1 2 3 4 5)
    echo "The original array is: ${myarray[*]}"
    arg1=$(echo ${myarray[*]})
    result=($(func1 $arg1))
    echo "The original array is: ${result[*]}"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    The original array is: 1 2 3 4 5
    The original array is: 2 4 6 8 10
    

    5.函数递归

    #!/bin/bash
    
    function factorial {
        if [ $1 -eq 1 ]
        then
            echo 1
        else 
            local temp=$[ $1 - 1 ]
            local result=$(factorial $temp)
            echo $[ $result * $1 ]
        fi
    }
    
    read -p "Enter value: " value
    result=$(factorial $value)
    echo "The factorial of $value is: $result"
    
    zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
    Enter value: 5
    The factorial of 5 is: 120
    

    相关文章

      网友评论

          本文标题:Shell基础

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