• Shell编程-03-Shell中的特殊变量和扩展变量


    特殊变量

        在Shell中的特殊变量主要分别两种位置参数变量状态变量两种。

    位置参数变量

        Shell中的位置参数变量主要是指$0、$1、$#等,主要用于从命令行、函数或脚本执行等地方传递参数。详细说明如下所示:

    • $0:获取当前执行的Shell脚本的文件名,如脚本中包含路径,则输出也包括路径
    • $n:获取当前执行的Shell脚本的第n个参数值,如n>9,则需要使用用大括号,如${10},各参数间用空格进行分隔
    • $#:获取当前执行的Shell脚本传入参数的总个数
    • $*:获取当前执行的Shell所有传入参数,如不加引号则与$@功能相同,如果添加双引号"$*",则表示将所有传入参数视为单个字符串,相当于"$1 $2 $3"
    • $@:获取当前执行的Shell所有传入参数,如不加引号则与$*功能相同,如果添加双引号"$@",则表示将所有传入参数视为独立的字符串,相当于"$1" "$2" "$3"

    当"$*"和"$@"都添加双引号时,两者的功能有所区别;如不加,则功能相同,无区别。

    位置参数变量示例

    1、示例一:

    [root@localhost Test]# cat para.sh
    #!/bin/bash
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
    echo '$0  is:' $0
    echo '$1  is:' $1
    echo '$12 is:' ${12}
    echo '$#  is:' $#
    echo '$*  is:' $*
    echo '"$*"is:' "$*"
    echo '$@  is:' $@
    echo '"$@"is:' "$@"
    # 输出结果
    [root@localhost Test]# bash ~/Test/para.sh {a..z}
    a b c d e f g h i j k l m n o
    $0  is: /root/Test/para.sh
    $1  is: a
    $12 is: l
    $#  is: 26
    $*  is: 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
    "$*"is: 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
    $@  is: 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
    "$@"is: 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
    

    1、传入的参数个数多于脚本定义的参数时,则多出的参数会忽略
    2、传入的参数中如使用双引号,则会当作一个参数值进行传递
    3、位置参数如大于9,需要使用${}进行传递

    2、示例二:

    [root@localhost Test]# cat testposition.sh 
    #!/bin/bash
    echo '$# $1 $2 $3 $* $@'
    echo $# $1 $2 $3 $*  $@
    echo "************"
    echo '$*'
    for tmp in $*
     do
       echo $tmp
     done
    echo "************"
    echo "@@@@@@@@@@@@"
    echo '$@'
    for temp in $@
     do
      echo $temp
     done
    echo "@@@@@@@@@@@@"
    
    echo '"*"*"*"*"*"*'
    
    echo '$*'
    for i in "$*"
     do
       echo $i
     done
    echo '"*"*"*"*"*"*'
    
    echo '"@"@"@"@"@"@'
    
    echo '$@'
    for j in "$@"
     do
      echo $j
     done
    echo '"@"@"@"@"@"@'
    
    [root@localhost Test]# bash testposition.sh  "Hello Jack" Welcome "to Shanghai"
    $# $1 $2 $3 $* $@
    3 Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai
    ************
    $* # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
    Hello
    Jack
    Welcome
    to
    Shanghai
    ************
    @@@@@@@@@@@@
    $@ # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
    Hello
    Jack
    Welcome
    to
    Shanghai
    @@@@@@@@@@@@
    "*"*"*"*"*"*
    $* # 添加双引号后,传入的参数全部当一个参数进行输出
    Hello Jack Welcome to Shanghai
    "*"*"*"*"*"*
    "@"@"@"@"@"@
    $@ # 添加双引号后,传入的参数全部当独立的参数进行输出
    Hello Jack
    Welcome
    to Shanghai
    "@"@"@"@"@"@
    

    状态变量

    • $?:获取上一个命令或脚本的执行状态值(0:成功,其他:失败)
    • $$:获取当前执行的Shell的进程号(PID)
    • $!:获取上一个在后台工作的进程的进程号
    • $_:获取在些之前执行的命令或脚本的最后一个参数

    以上四个状态变量,仅$?常用,其他三个了解即可。

    在日常使场景中,$?主要用法如下所示:

    • 1、判断命令和脚本是否执行成功
    • 2、如脚本中调用exit 数字,则会返回该数字给$?
    • 3、如在函数中,则可以通过return 数字将该数字返回给$?

    状态变量示例

    1、$?示例:

    [root@localhost Test]# ll /etc/profile
    -rw-r--r--. 1 root root 1819 4月  11 2018 /etc/profile
    [root@localhost Test]# echo $?
    0
    [root@localhost Test]# ll /etc/profild
    ls: 无法访问/etc/profild: 没有那个文件或目录
    [root@localhost Test]# echo $?
    2
    

    2、$$示例:

    [root@localhost Test]# cat testPID.sh
    #!/bin/bash
    echo $$ > /tmp/test.pid
    sleep 300
    
    [root@localhost Test]# bash testPID.sh  & # 将当前脚本调用到后台执行
    [1] 1671
    [root@localhost Test]# ps -ef | grep testPID | grep -v grep
    root      1671 23706  0 16:37 pts/0    00:00:00 bash testPID.sh # 查询PID
    

    3、$!示例:
        $!功能类似于$$,只不过是获取上一次执行脚本的PID

    [root@localhost Test]# bash testPID.sh  &
    [1] 24078
    [root@localhost Test]# echo $!
    24078 # 打印上一次在后台执行的进程号
    [root@localhost Test]# ps -ef | grep testPID | grep -v grep
    root     24078 23706  0 16:42 pts/0    00:00:00 bash testPID.sh
    

    4、$_示例:

    [root@localhost Test]# bash para.sh {a..z}
    a b c d e f g h i j k l m n o
    $0  is: para.sh
    $1  is: a
    $12 is: l
    $#  is: 26
    $*  is: 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
    "$*"is: 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
    $@  is: 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
    "$@"is: 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@localhost Test]# echo $_
    z # 打印最后一个传入的参数值
    

    Bash 内置变量

        常用的内部命令有echo、eval、exec、export、read、shift、exit

    echo

        主要用于打印信息,其命令格式如下所示:

    echo [options] args
    

    常用参数如下所示:

    参数选项 说明
    -n 不换行输出内容
    -e 解析转义字符

    echo常用转义字符如下:

    转义字符 说明
    换行
    回车
    Tab
     退格
    v 纵向制表符
    eval

        当Shell程序运行到eval语句时,将读入参数args,并将它们组合成一个新的命令而后执行。其命令格式如下所示:

    eval args
    
    exec

        exec主要用于在不创建新的子进程的情况下,转而执行指定的命令,当指定命令执行完后,则终止该进程。其命令格式如下所示:

    exec args
    

    当使用exec打开文件后,read命令每次都会将文件指针移动到下一行进行读取,直至结束。因此常用来处理文件内容。

    read

        从标准输入读取变量或字符串等信息并传递给其他变量,其命令格式如下所示

    read args
    
    shift

        对传入的位置参数依次向左移动一个位置,并使用位置参数$#减1,直至0为止。其命令格式如下所示:

    shift postition args
    

    shift如果不带参数,则默认左移1位
    如传入的参数为$1 $2 $3,如执行一次shift,则之前的$3变成$2,$2变成$1,$1消失。

    exit

        常用于退出Shell,在日常使用过程中可使用exit num来自定义返回状态数。

    Bash 内置变量示例

    1、echo

    [root@localhost Test]# echo "Test";echo "Dao"
    Test
    Dao
    [root@localhost Test]# echo -n "Test";echo "Dao"
    TestDao
    [root@localhost Test]# echo -e "Test	Name
     Dao"
    Test    Name
     Dao
    

    2、eval

    [root@localhost Test]# cat eval.sh
    #!/bin/bash
    
    echo "No eval"
    echo $$#
    echo "Add eval"
    eval echo $$#
    
    [root@localhost Test]# bash eval.sh  a b
    No eval
    $2 # 未添加evel时,$#为2,则输出$2
    Add eval
    b  # 添加evel后,则重新对传入的参数进行解析,则输出传入的第2个参数
    

    3、exec

    [root@localhost Test]# exec ls
    eval.sh  para.sh  ping.sh  testPID.sh  testposition.sh
    [admin@localhost ~]$  # 在执行exec后则终止当前Shell进程,因此从root用户退出到普通用户
    # 与read一起读取文件
    [root@localhost ~]# seq 5 > /tmp/rand.log
    [root@localhost ~]# cat /tmp/rand.log 
    1
    2
    3
    4
    5
    [root@localhost Test]# cat exec.sh
    #!/bin/bash
    exec < /tmp/rand.log
    while read line
     do
      echo $line
     done
    echo "Completed"
    
    [root@localhost Test]# bash exec.sh
    1
    2
    3
    4
    5
    Completed
    

    4、read
    可以参考公众号中read命令一文

    5、shift

    [root@localhost Test]# cat shift.sh
    #!/bin/bash
    echo $1 $2 $3 $4 $5
    until [ -z $1 ]
    do
      echo $@
      shift 1
    done
    [root@localhost Test]# bash shift.sh {1..5}
    1 2 3 4 5
    1 2 3 4 5
    2 3 4 5
    3 4 5
    4 5
    5
    

    变量扩展

    变量扩展说明

        Shell中变量扩展说明如下所示:

    • ${var}:返回${var}的内容
    • ${#var}:返回${var}的字符长度
    • ${var:offset}:返回${var}从位置offset之后开始提取字符至结束
    • ${var:offset:length}:返回${var}从offset之后,提取长度为length的字符
    • ${var#word}:返回从${var}开头开始删除最短匹配的word子符串
    • ${var##word}:返回从${var}开头开始删除最长匹配的word子符串
    • ${var%word}:返回从${var}结尾开始删除最短匹配的word子符串
    • ${var%%word}:返回从${var}结尾开始删除最长匹配的word子符串
    • ${var/oldstring/newstring}:使用newstring替换第一个匹配的字符oldstring
    • ${var//oldstring/newstring}:使用newstring替换所有匹配的字符oldstring
    • ${var:-word}:如果变量var的值为空或未赋值,则将word做为返回值,常用于防止变量为空或未定义而导致的异常
    • ${var:=word}:如果变量var的值为空或未赋值,则将word赋值给var并返回其值。
    • ${var:?word}:如果变量var的值为空或未赋值,则将word做为标准错误输出,否则则输出变量的值,常用于捕捉因变量未定义而导致的错误并退出程序
    • ${var:+word}:如果变量var的值为空或未赋值,则什么都不做,否则word字符将替换变量的值
    其中${var:-word}、${var:=word}、${var:?word}、${var:+word}中的冒号也可以省略,则将变量为空或未赋值修改为未赋值,去掉了为空的检测, 即运算符仅检测变量是否未赋值
    

    变量扩展示例

    [root@localhost init.d]# var="This is test string"
    [root@localhost init.d]# echo $var
    This is test string
    [root@localhost init.d]# echo ${var}
    This is test string
    [root@localhost init.d]# echo ${#var} # 统计字符长度
    19
    [root@localhost init.d]# echo ${var:5} # 从第5个位置开始截取字符
    is test string
    [root@localhost init.d]# echo ${var:5:2} # 从第5个位置开始截取2个字符
    is
    [root@localhost init.d]# echo ${var#This} # 从开头删除最短匹配的字符 is
    is test string
    [root@localhost init.d]# echo ${var##This}  # 从开头删除最长匹配的字符 is
    is test string
    [root@localhost init.d]# echo ${var%g} # 从结尾删除最短匹配的字符 is
    This is test strin
    [root@localhost init.d]# echo ${var%%g} # 从结尾删除最长匹配的字符 is
    This is test strin
    [root@localhost init.d]# echo ${var/is/newis} # 替换第一个匹配的字符
    Thnewis is test string
    [root@localhost init.d]# echo ${var//is/newis} # 替换所有匹配到的字符
    Thnewis newis test string
    
    [root@localhost init.d]# echo $centos # 变量未定义
    
    [root@localhost init.d]# echo ${centos:-UNDEFINE} # 变量为空,返回UNDEFINE
    UNDEFINE
    [root@localhost init.d]# centos="CentOS"
    [root@localhost init.d]# echo ${centos:-UNDEFINE} # 变量已经定义,返回变量本身的值
    CentOS
    [root@localhost init.d]# unset centos # 取消变量值
    [root@localhost init.d]# echo $centos
    
    [root@localhost init.d]# result=${centos:=UNDEFINE}
    [root@localhost init.d]# echo $result
    UNDEFINE
    [root@localhost init.d]# echo $centos # 变量值为空,则将UNDEFINE赋值给centos
    UNDEFINE
    [root@localhost init.d]# unset centos
    [root@localhost init.d]# echo ${centos:?can not find variable centos}
    
    -bash: centos: can not find variable centos  # 变量值为空,输出自定义错误信息
    
    [root@localhost init.d]# centos="IS DEFINED"
    [root@localhost init.d]# echo ${centos:?can not find variable centos}
    IS DEFINED               #变量值已定义,则输出变量值
    [root@localhost init.d]# unset centos
    [root@localhost init.d]# echo ${centos:+do nothing} # 变量值为空,什么都不操作输出
    
    [root@localhost init.d]# centos="do"
    [root@localhost init.d]# echo ${centos:+do nothing}  # 变量已赋值,则输出自定义的消息
    do nothing
    

    本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:
    MyQRCode.jpg

  • 相关阅读:
    浅析C# new 和Override的区别
    用流打开open office ods 文件
    两个自己写的合并GridView 行的方法
    TSQL 日期格式化
    页面刷新后滚动条定位
    解决 TextBox 的 ReadOnly 属性为 true 时,刷新页面后值丢失的方法
    Sql server 查询条件中将通配符作为文字使用
    window.open 弹出页面回写父页面值及触发父页面Button事件
    注册光标丢失的事件
    模态对话框对父页面控件回写值
  • 原文地址:https://www.cnblogs.com/surpassme/p/9932841.html
Copyright © 2020-2023  润新知