美文网首页测试人学linux
《Linux从入门到精通》之shell编程

《Linux从入门到精通》之shell编程

作者: Tomandy | 来源:发表于2018-04-17 19:55 被阅读24次

    shell变量

    变量名和等号之间不能有有空格,变量名命名遵循以下规则。

    • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    • 中间不能有空格,可以使用下划线(_)。
    • 不能使用bash里的关键字(可用help命令查看保留关键字)。
    my_name="Tomandy"
    echo ${my_name}            #输出 Tomandy
    echo ${my_name}123         #输出 Tomandy123
    

    使用关键字readonly可以将变量定义为只读变量,该类型变量的值不能被改变。

    myname="Tomandy"
    readonly myname
    myname="andy"              #执行报错 myname只读变量
    

    unset可以删除变量,但是不能删除只读变量。

    myname="Tomandy"
    unset myname
    echo ${myname}             #执行没有任何输出
    

    shell字符串

    单引号字符串和双引号字符串的区别。

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的。
    • 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
    • 双引号里可以有变量。
    • 双引号里可以出现转义字符。
    myname='myname is tomandy'
    echo '${myname}'            #输出 ${myname}
    echo "${myname}"            #输出 myname is tomandy
    

    获取字符串长度

    string="Lin 123"
    echo ${#string}             #输出 7
    expr length "$string"       #输出 7,注意由于string变量有空格,变量需加上“”
    

    提取子字符串

    string="myname is Tomandy"
    echo ${string:1:4}          # 输出 ynam,表示从第二个字符开始,截取4个字符
    

    字符串截取的其他方法如下:
    假设有变量 var=http://www.aaa.com/123.htm

    1. # 号截取,删除左边字符,保留右边字符。
    echo ${var#*//} 
    # 其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 //号及左边的所有字符,即删除http://
    # 输出结果是 :www.aaa.com/123.htm
    
    1. ## 号截取,删除左边字符,保留右边字符。
    echo ${var##*/}
    # “##*/” 表示从左边开始删除最后(最右边)一个/号及左边的所有字符,即删除 http://www.aaa.com/
    # 输出结果是 :123.htm
    
    1. %号截取,删除右边字符,保留左边字符。
    echo ${var%/*}
    # %/* 表示从右边开始,删除第一个 / 号及右边的字符,即/123.htm
    # 输出结果是:http://www.aaa.com
    
    1. %% 号截取,删除右边字符,保留左边字符。
    echo ${var%%/*}
    # %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
    # 输出结果是:http:
    
    1. 从左边第几个字符开始,一直到结束。
    echo ${var:7}
    # 其中的 7 表示左边第8个字符开始,一直到结束。
    # 输出结果是 :www.aaa.com/123.htm
    
    1. 从右边第几个字符开始,及字符的个数。
    echo ${var:0-7:3}
    # 其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
    # 输出结果是:123
    
    1. 从右边第几个字符开始,一直到结束
    echo ${var:0-7}
    # 表示从右边第七个字符开始,一直到结束。
    # 输出结果是:123.htm
    

    查找字符串

    string="Tomandy is a man"
    echo `expr index "$string" is`  #输出9,注意此处使用了反引号,而不是单引号
    

    shell数组

    在Shell中,用括号来表示数组,数组元素用"空格"符号分割开。定义及读取数组如下所示:

    array_name=(value0 value1 value2 value3) #定义数组
    value=${array_name[n]}    #读取数组某个元素值
    echo ${array_name[@]}     #获取数组所有元素
    length=${#array_name[@]}  #获取数组个数
    length=${#array_name[*]}  #获取数组个数
    lengthn=${#array_name[n]} #取得数组单个元素的长度
    

    数组的值也可以写入变量,如:my_array=($A B C D),A为变量。

    shell参数传递

    我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

    参数处理 说明
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

    其他特殊字符:

    参数处理 说明
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

    $* 与 $@ 区别:
    相同点:都是引用所有参数。
    不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。通过循环打印可以发现差异。

    shell文件测试运算符

    文件测试运算符.png

    echo命令

    标准输入:read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。

    #!/bin/sh
    read name    #read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
    echo "$name It is a test"
    

    显示换行:

    echo -e "OK! \n"    # -e 开启转义
    echo "It it a test"
    
    #输出结果
    OK!  
    
    It it a test
    

    显示不换行:

    #!/bin/sh
    echo -e "OK! \c"      # -e 开启转义 \c 不换行
    echo "It is a test"
    
    #输出结果
    OK! It it a test
    

    其他示例:

    read -p "请输入一段文字:" -n 6 -t 5 -s password
    echo -e "\npassword is $password"  #-e开启转义
    
    • -p 输入提示文字
    • -n 输入字符长度限制(达到6位,自动结束)
    • -t 输入限时
    • -s 隐藏输入内容
    #执行结果
    $ sh test.sh 
    请输入一段文字:
    password is asdfgh
    

    test命令

    test命令等价于[],下图两段代码输出结果为“两个数相等”

    num1=100
    num2=100
    if test ${num1} -eq ${num2}
    then
        echo '两个数相等!'
    else
        echo '两个数不相等!'
    fi
    
    num1=100
    num2=100
    if [ ${num1} -eq ${num2} ]
    then
        echo '两个数相等!'
    else
        echo '两个数不相等!'
    fi
    

    Shell 流程控制

    if else语法

    if condition
    then
        command1 
        command2
        ...
        commandN 
    fi
    
    if condition
    then
        command1 
        command2
        ...
        commandN
    else
        command
    fi
    
    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    

    for循环:

    for var in item1 item2 ... itemN
    do
        command1
        command2
        ...
        commandN
    done
    
    #!/bin/bash
    for((i=1;i<=5;i++));do
        echo "这是第 $i 次调用";
    done;
    

    while循环:

    #!/bin/sh
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"       #用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
    done
    
    #while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。
    echo '按下 <CTRL-D> 退出'
    echo -n '输入你最喜欢的网站名: '
    while read FILM
    do
        echo "是的!$FILM 是一个好网站"
    done
    

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

    echo '输入 1 到 4 之间的数字:'
    echo '你输入的数字为:'
    read aNum
    case $aNum in
        1)  echo '你选择了 1'
        ;;
        2)  echo '你选择了 2'
        ;;
        3)  echo '你选择了 3'
        ;;
        4)  echo '你选择了 4'
        ;;
        *)  echo '你没有输入 1 到 4 之间的数字'
        ;;
    esac
    

    shell函数

    举例如下:

    #!/bin/bash
    
    demoFun(){
        echo "这是我的第一个 shell 函数!"
    }
    echo "-----函数开始执行-----"
    demoFun
    echo "-----函数执行完毕-----"
    
    
    #输出结果
    -----函数开始执行-----
    这是我的第一个 shell 函数!
    -----函数执行完毕-----
    
    #!/bin/bash
    
    funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
        read aNum
        echo "输入第二个数字: "
        read anotherNum
        echo "两个数字分别为 $aNum 和 $anotherNum !"
        return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"      #函数返回值在调用该函数后通过 $? 来获得。 
    
    
    #输出结果
    这个函数会对输入的两个数字进行相加运算...
    输入第一个数字: 
    1
    输入第二个数字: 
    2
    两个数字分别为 1 和 2 !
    输入的两个数字之和为 3 !
    
    #在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
    #!/bin/bash
    
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    

    /dev/null 文件

    如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null。
    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

    Shell 文件包含

    创建两个 shell 脚本文件。
    test1.sh 代码如下:

    #!/bin/bash
    
    url="http://www.runoob.com"
    

    test2.sh 代码如下:

    #!/bin/bash
    
    #使用 . 号来引用test1.sh 文件
    . ./test1.sh
    
    # 或者使用以下包含文件代码
    # source ./test1.sh
    
    echo "网址:$url"
    

    相关文章

      网友评论

      • cooling2016:这么认真,比赛都不看了
        Tomandy:@cooling2016 比赛还是关注的,不过只能看文字直播 😓

      本文标题:《Linux从入门到精通》之shell编程

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