zoukankan      html  css  js  c++  java
  • shell 学习笔记3-shell变量扩展

    一、特殊位置参数变量

      1、特殊位置参数变量

        在shell中比如:$0、$1、$#,等被称为特殊位置参数变量,当命令行、函数、脚本执行等处传递参数时,就需要使用位置参数变量

        参数说明如下:

     

      2、示例$1$2...$9${10}${11}...

        1)测试$n(n为1..15)

    [root@web1 scripts]# vim test1.sh       #<---创建test1.sh脚本
    #!/bin/bash
    echo $1                     #<---打印脚本传递的第一个参数的值
    [root@web1 scripts]# chmod +x test1.sh   #<---授权
    [root@web1 scripts]# ./test1.sh       #<---不加参数输出空白
    
    [root@web1 scripts]# ./test1.sh zxg    #<---加一个参数
    zxg
    [root@web1 scripts]# ./test1.sh zxg shell  #<---加两个参数,只输出第一个参数
    zxg
    [root@web1 scripts]# ./test1.sh "zxg shell"  #<---添加双括号,两个都输出因为加双括号会作为一个字符串参数
    zxg shell
    [root@web1 scripts]#                                 

        2)同时加入$1和$2,并进行测试

    [root@web1 scripts]# cat test2.sh               #<---创建test2.sh脚本
    #!/bin/bash
    echo $1 $2
    
    [root@web1 scripts]# chmod +x test2.sh          #<---加权限
    [root@web1 scripts]# ./test2.sh zxg shell        #<---运行
    zxg shell                            
    [root@web1 scripts]# ./test2.sh "zxg shell" 2019    #<---对又空格的字符串需要双引号才能正常使用
    zxg shell 2019
    [root@web1 scripts]# 

        3)设置15个位置参数($1~$15),用于接收命令行传递的15个参数

    [root@web1 scripts]# echo ${1..15}                       #<---利用大括号输出15个位置参数,10大技巧
    $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
    [root@web1 scripts]# echo ${1..15} >test3.sh
    [root@web1 scripts]# cat test3.sh 
    $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
    [root@web1 scripts]# echo {a..z}
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    [root@web1 scripts]# chmod +x test3.sh                                                
    [root@web1 scripts]# cat test3.sh 
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
    [root@web1 scripts]# ./test3.sh {a..z}            #<---运行发现就到9 超过9必须用大括号
    a b c d e f g h i a0 a1 a2 a3 a4 a5
    [root@web1 scripts]# 

     [root@web1 scripts]# cat test3.sh
     echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}  #这样就可以正常了
     [root@web1 scripts]# ./test3.sh {a..z}
     a b c d e f g h i j k l m n o
     [root@web1 scripts]#

    
    

      3、$0特殊变量的作用示例

        取出执行脚本的名称(包括路径)

        1)、获得脚本名称及路径

    [root@web1 scripts]# cat test4.sh 
    #!/bin/bash
    echo $0
    
    [root@web1 scripts]# chmod +x test4.sh 
    [root@web1 scripts]# ./test4.sh 
    ./test4.sh
    [root@web1 scripts]# 

     [root@web1 scripts]# sh /scripts/test4.sh           #<---带路径的话,就会输出路径加名字
     /scripts/test4.sh
     [root@web1 scripts]#

     

        2)单独获取名称或路径的方法

    [root@web1 scripts]# dirname /scripts/test4.sh   #<---dirname命令作用时获取脚本路径
    /scripts
    [root@web1 scripts]# basename /scripts/test4.sh  #<---basename命令则时获取脚本名称
    test4.sh
    [root@web1 scripts]# 

        3)利用$0 和(dirname、basename)分别读取脚本名称和脚本路径

    [root@web1 scripts]# cat test5.sh 
    #!/bin/bash
    dirname $0
    basename $0
    
    [root@web1 scripts]# chmod +x test5.sh 
    [root@web1 scripts]# sh /scripts/test5.sh
    /scripts
    test5.sh
    [root@web1 scripts]# 

      4、$#特殊变量获取脚本传参个数的示例

        1)通过$#获取脚本传参的个数

    [root@web1 scripts]# cat test6.sh 
    #!/bin/bash
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9
    echo $#
    [root@web1 scripts]# chmod +x test6.sh 
    [root@web1 scripts]# ./test6.sh {a..z}   #<---传入26个参数
    a b c d e f g h i               #<---只打印了9个
    26                        #<---代表26个参数
    [root@web1 scripts]# 

        2)根据用户在命令行的传参个数判断用户的输入,不合要求的给予提示并退出

          这是针对$0、$1、$#等多位置参数的综合示例

    [root@web1 scripts]# cat test7.sh 
    #!/bin/bash
    [ $# -ne 2 ] && {                #<---如果执行脚本传参的个数不等于2
            echo "muse two args"          #<---则给用户提示正确的用法
            exit 1                  #<---由于不满足要求,因此退出脚本,返回值为1
    }
    echo abc                      #<---满足了参数个数的传参要求,就执行判断后的程序脚本,打印abc
    [root@web1 scripts]# chmod +x test7.sh
    [root@web1 scripts]# ./test7.sh 
    muse two args
    [root@web1 scripts]# ./test7.sh  1 2
    abc
    [root@web1 scripts]# 

          if语句的写法

    [root@web1 scripts]# cat test8.sh 
    #!/bin/bash
    if [ $# -ne 2 ] 
            then
                    echo "USAGE:/bin/bash $0  arg1 arg2" 
            exit 1
    fi
    echo $1 $2
    [root@web1 scripts]# chmod +x test8.sh
    [root@web1 scripts]# ./test8.sh 
    USAGE:/bin/bash ./test8.sh  arg1 arg2
    [root@web1 scripts]# ./test8.sh 1 3
    1 3
    [root@web1 scripts]# 

      5、$*和$@特殊变量功能及区别示例

        1)利用set设置位置参数(同命令行脚本的传参)

    [root@web1 scripts]# set -- "i am" zxg shell 
    [root@web1 scripts]# echo $#
    3
    [root@web1 scripts]# echo $1 
    i am
    [root@web1 scripts]# echo $2
    zxg
    [root@web1 scripts]# echo $3
    shell
    [root@web1 scripts]# 

        测试$*和$@,注意,此时带双引号

    [root@web1 scripts]# echo "$*"                
    i am zxg shell
    [root@web1 scripts]# echo "$@"
    i am zxg shell
    [root@web1 scripts]# for i in "$*";do echo $i;done    #<---在又双引号的情况下,"$*",引号里面当作一个参数输出
    i am zxg shell
    [root@web1 scripts]# for i in "$@";do echo $i;done     #<---在又双引号的情况下,"$#",每个参数独立输出,
    i am                                #<---算一个参数
    zxg
    shell
    [root@web1 scripts]# for i ;do echo $i;done        #<---去掉in 变量列表,相当于又引号的in "$@"
    i am
    zxg
    shell
    [root@web1 scripts]# for i in $*;do echo $i;done      #<---$*不加双引号,因此会输出所有参数,然后第一个参数"i am"也拆开输出了
    i
    am
    zxg
    shell
    [root@web1 scripts]# shift                  #<---用shift将位置参数移位(左移)
    [root@web1 scripts]# echo $#
    2
    [root@web1 scripts]# echo $1                 #<---这里就打印原来$2的值
    zxg
    [root@web1 scripts]# echo $2                 #<---这里就打印原来$3的值
    shell
    [root@web1 scripts]# 

     

    二、shell进程中的特殊状态变量

     

      1、$?示例

        1)执行命令

    [root@web1 scripts]# pwd 
    /scripts
    [root@web1 scripts]# echo $?          #<---返回0表示上一个命令成功
    0
    [root@web1 scripts]# ls /root
    anaconda-ks.cfg  Desktop    google-chrome-stable_current_x86_64.rpm  original-ks.cfg
    bash-test        Downloads  initial-setup-ks.cfg
    [root@web1 scripts]# lss /root
    bash: lss: command not found...
    Similar command is: 'ls'
    [root@web1 scripts]# echo $?          #<---非零表示上一个命令失败
    127
    [root@web1 scripts]# 

        可以利用$?判断安装、打包、备份等执行是否正确成功

          tar zcf /zxg/zxg.tar.gz /zxg/zxg

          echo $?

        2)通过脚本控制命令及脚本执行后的返回值

    [root@web1 scripts]# cat test9.sh 
    #!/bin/bash
    [ $# -ne 2 ] && {                    #<---参数格式不等于2
    echo "must be two args"            #<---输出提示 exit 119                          #<---终止程序运行并以制定的119状态值退出程序赋值给$? } echo zxg [root@web1 scripts]# chmod +x test9.sh [root@web1 scripts]# ./test9.sh 1 2 zxg [root@web1 scripts]# echo $? 0 [root@web1 scripts]# ./test9.sh must be two args [root@web1 scripts]# echo $? 119 [root@web1 scripts]#

        3)小结

          判断命令、脚本或函数程序是否执行成功

          若在脚本中调用执行exit 数字 把这个数字以函数返回值的形式传给$?变量

          如果是在函数里,则通过return数字把这个数字以函数返回值的形式传给$?

      2、$$特殊变量功能及实践

        1)获取脚本执行的进程号

    [root@web1 scripts]# cat test10.sh 
    #!/bin/bash
    echo $$ >/tmpa.pid                                #<---获取$$的值,并重定向
    sleep 300                                      #<---休息300s,模拟守护进程不退出
    [root@web1 scripts]# chmod +x test10.sh 
    [root@web1 scripts]# ps -ef|grep test10|grep -v grep              
    [root@web1 scripts]# ./test10.sh &                       #<---后台运行
    [1] 49825
    [root@web1 scripts]# ps -ef|grep test10|grep -v grep            #<---查找进程号
    root      49825  36709  0 18:23 pts/1    00:00:00 /bin/bash ./test10.sh
    [root@web1 scripts]# cat /tmpa.pid                       #<---对应$$的值
    49825
    [root@web1 scripts]# 

         2)实现系统中多次执行某个脚本后的进程只有一个-企业级应用,用于执行启动或定时任务

    [root@web1 scripts]# cat test11.sh 
    #!/bin/bash
    pidpath=/tmp/a.pid                              #<---定义pid文件
    if [ -f "$pidpath" ]                             #<---如果pid文件存在,值=则执行then后面的命令
            then
                    kill `cat $pidpath` >/dev/null 2>&1          #<---杀掉与前一个金朝赌赢的进程
                    rm -f $pidpath                       #<---删除pid文件
    fi
    echo $$ >$pidpath                               #<---将当前$$值记录到pid文件里
    sleep 300
    [root@web1 scripts]# chmod +x test11.sh 
    [root@web1 scripts]# ./test11.sh 
    ^C
    [root@web1 scripts]# ./test11.sh &
    [1] 49966
    [root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
    root      49966  36709  0 18:35 pts/1    00:00:00 /bin/bash ./test11.sh
    [root@web1 scripts]# ./test11.sh &                      
    [2] 49981
    [root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
    root      49981  36709  0 18:36 pts/1    00:00:00 /bin/bash ./test11.sh
    [1]-  Terminated              ./test11.sh
    [root@web1 scripts]# ./test11.sh &                                  #<---无论执行多少次脚本每次都会将上一次运行的杀掉,都只有一个进程
    [3] 49988
    [root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
    root      49988  36709  0 18:36 pts/1    00:00:00 /bin/bash ./test11.sh
    [2]-  Terminated              ./test11.sh
    [root@web1 scripts]# 

      3、$_特殊变量功能说明及实践

         获得上一条命令的最后一个参数,用的不多

    [root@web1 scripts]# systemctl restart httpd zxg
    Failed to restart zxg.service: Unit not found.
    Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
    [root@web1 scripts]# echo $_
    zxg
    [root@web1 scripts]# 

      4、$!特殊变量功能说明及实践

        $!的功能类似$$,只不过作用是获取上次执行脚本的pid,了解就可以了

    [root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep 
    [root@web1 scripts]# echo $!
    49988
    [root@web1 scripts]# 

    转载请注明出处:https://www.cnblogs.com/zhangxingeng/p/11128349.html 

  • 相关阅读:
    socket 第一课
    _getitem__ __setitem__ __delitem__ __len__
    单继承&多继承 注意点
    面对对象 类&对象
    异常检测
    模块导入
    序列化模块注意点 json&pickle
    re模块
    filter和map
    Maven入门
  • 原文地址:https://www.cnblogs.com/zhangxingeng/p/11128349.html
Copyright © 2011-2022 走看看