Linux shell 编程(四):变量

变量

变量是能储存计算结果或能表示值抽象概念。变量能够经过变量名访问。html

变量声明

声明变量通常使用下面方式:shell

root@iZuf6ilzd4iqvuj4dvuiwtZ:~# var=test #这里声明了一个名为 var 的变量,并给他赋值为test
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# # “=”先后不能有空格,变量名区分大小写

或者下面方式:数组

root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# declare var1=123
root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# export var2=234
root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# 
root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# env var3=333

上面使用的命令:declare,export,env 均可以声明变量,区别在于变量做用域不一样。
shell有两种变量:bash

  • shell局部变量
    局部变量在脚本或命令中定义,仅在当前shell实例中有效,其余shell启动的程序不能访问局部变量。
    经过赋值语句定义好的变量,能够经过以下方法定义shell变量
    root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# declare var1=123
    root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# var1=123ide

  • 用户环境变量
    全部的程序,包括shell启动的程序,都能访问环境变量,有些程序须要环境变量来保证其正常运行。必要的时候shell脚本也能够定义环境变量。
    经过export语法导出的shell私有变量,能够经过以下方法导出用户环境变量
    export x =2
    declare -x x=2

变量使用

显示shell变量

  • env 这是一个工具,或者说一个Linux命令,显示用户的环境变量。
  • set 显示用户的局部变量和用户环境变量。
  • export 显示导出成用户变量的shell局部变量,并显示变量的属性;就是显示由局部变量导出成环境变量的那些变量 (好比能够 export WWC导出一个环境变量,也可经过 declare -X LCY导出一个环境变量)
  • declare 跟set同样,显示用户的shell变量 (局部变量和环境变量)

declare命令:

# 语法:declare [-aAfFgilnrtux] [-p] [name[=value] ...]
    # 描述: declare 用来声明变量和配置变量的属性,若是declare后面没有参数,将会显示所有变量的属性和值。
    # 参数
                -f   限制行动或显示函数名称和定义
                -F  只限制显示函数名(加上行号和源文件时调试)
                -g  在shell函数中使用时建立全局变量;不然忽略
                -p  显示每一个变量的属性和值。

    # 属性设置参数
                -a  声明一个索引数组
                -A  声明一个聚合数组
                -i   变量值为整数,当给变量赋值为非整数值时变量为0
                -l   给变量赋值时转换成小写字母
                -n  将名称引用为其值命名的变量。
                -r   只读变量 # 使用readonly命令也能够设置变量只读
                -t  使名称具备“trace”属性
                -u  给变量赋值时转换成大写字母
                -x  导出变量到用户环境变量

export命令

# 语法: export [-fn] [name[=value] ...] or export -p
    # 描述:从shell变量导出属性,将自动导出的每一个名称标记为随后执行的命令的环境。若是提供了值,则在导出以前分配值。
    # 参数
     -f     引用shell函数
     -n     从每一个变量删除导出属性
     -p     显示已导出的函数和变量清单

set 命令

# 语法:set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
    # 描述:设置或取消shell参数和位置参数的值。更改shell属性和位置参数的值,或显示shell变量的名称和值。

    # 参数:
      -a  标记为导出而修改或建立的变量。
      -b  当即通知终止任务。
      -e  若是有非零状态的命令退出,当即退出。
      -f  禁用文件名称生成(全局)。
      -h  记住所查找的命令位置。
      -k 全部的赋值参数都放置在一个命令的环境中,而不只仅是在命令名前面的命令。
      -m  开启任务控制。
      -n  读取命令,但不执行它们。
      -o option-name
          设置对应于选项名的变量:
              allexport    与-a相同
              braceexpand  与-B相同
              emacs        使用emacs样式的行编辑界面。
              errexit      与-e相同
              errtrace     与-E相同
              functrace    与-T相同
              hashall      与-h相同
              histexpand   与-H相同
              history      开启命令历史
              ignoreeof    读取EOF时shell不会退出
              interactive-comments
                           容许注释出如今交互式命令行中
              keyword      same as -k
              monitor      same as -m
              noclobber    same as -C
              noexec       same as -n
              noglob       same as -f
              nolog        目前接受但忽略
              notify       same as -b
              nounset      same as -u
              onecmd       same as -t
              physical     same as -P
              pipefail     管道的返回值是最后一个以非零状态退出的命令的状态,若是没有非零状态的命令退出,则为零。
              posix        更改bash的行为,默认操做与Posix标准不一样,以匹配标准。
              privileged   same as -p
              verbose      same as -v
              vi           使用vi样式的行编辑界面
              xtrace       same as -x
      -p  当真实有效的用户id不匹配时打开。取消对$ENV文件的处理和shell函数的导入。关闭这个选项会致使有效的uid和gid设置为真正的uid和gid。
      -t  读取和执行一个命令后退出。
      -u  在替换时将未设置的变量视为一个错误。
      -v  打印shell的输入行。
      -x  打印命令及其执行时的参数。
      -B  shell将执行支撑扩展
      -C  若是设置,则不容许经过重定向输出来覆盖现有的常规文件。
      -E  若是设置,ERR捕获是由shell函数继承的。
      -H  启用!风格历史替换。当shell是交互式的时,这个标志是默认的。
      -P  若是设置,在执行命令(例如更改当前目录的cd)时,不要解析符号连接。
      -T  若是设置,DEBUG捕获从shell函数继承
      --  将剩余的参数分配给位置参数。若是没有剩下的参数,那么位置参数就没有设置。
      -   将剩余的参数分配给位置参数。-x和-v选项关闭。

env命令

# 描述: 在修改的环境中运行程序,将每一个名称设置为环境中的值并运行命令。对长参数的强制参数也必须是短参数。
    # 语法: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
    # 参数
        -i, --ignore-environment
              从一个空的环境开始。

        -0, --null
              用NUL,而不是newline结束每一个输出行。

        -u, --unset=NAME
              从环境中删除变量。

    # 若是没有参数则打印当前环境中的变量

变量做用域

shell变量

shell变量至关于一个全局变量,能够在子shell,函数中使用。在函数中直接声明一个变量或者使用declare -g 声明变量,则此变量为全局变量。函数

如:工具

# variable=value
# declare variable=value

函数变量

使用local命令能够声明一个函数(局部)变量,此变量只能在函数内访问,若是不适用local命令,则此变量为shell(全局)变量。ui

function test(){
    variable=123; # 全局变量
    declare -g v=2 # 全局变量
    local a=123 # 函数(局部)变量,只能在函数内访问
}

变量取消

使用unset命令能够删除变量命令行

unset命令

# 语法: unset [-f] [-v] [-n] [name ...]
    # 描述: 撤销shell变量和函数的值和属性。对于每一个名称,删除相应的变量或函数。
    # 参数:
        -f  将name参数视为函数
        -v  将name参数视为变量
        -n  每一个名称视为一个名称引用,并将变量自己设置为unset。而不是它引用的变量。
        # 没有选项,unset首先尝试取消设置一个变量,若是失败,则尝试取消设置一个函数。
        # 注意:只读变量不能被unset
        root@iZuf6ilzd4iqvuj4dvuiwtZ:~# declare -r NAME=raojl
        root@iZuf6ilzd4iqvuj4dvuiwtZ:~# unset NAME
        -bash: unset: NAME: cannot unset: readonly variable
        root@iZuf6ilzd4iqvuj4dvuiwtZ:~#

变量调用

在声明变量一个变量时变量名称要遵照下列规则:调试

  1. 不能以特殊字符(除了_),数字,美圆符($)开头
  2. 变量名不能是纯数字
  3. 变量名能够是英文或数字或特殊字符(_)的组合

调用变量时在变量明前面以$var的形式调用变量,如:

root@iZuf6ilzd4iqvuj4dvuiwtZ:~# name=raojl # 声明一个名为name的变量并赋值为raojl
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo $name # 调用变量name
raojl  # name的值
root@iZuf6ilzd4iqvuj4dvuiwtZ:~#

变量名能够在双引号""内使用,shell会解释引号内的变量,在''则不会解释变量。如:

root@iZuf6ilzd4iqvuj4dvuiwtZ:~# name=raojl
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo "$name" # shell会解释引号内的变量name
raojl # 变量name的值
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo '$name' # shell不会解释name
$name # 原样输出,不会解释
root@iZuf6ilzd4iqvuj4dvuiwtZ:~#

也可使用大括号${variable}的形式将变量包裹起来,为了不变量名被其余字符干扰,可使用此方式,如:

root@iZuf6ilzd4iqvuj4dvuiwtZ:~# hello=Hello
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo "$helloWorld" # shell将会解释变量 hellworld

root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo "${hello}World" # shell将会解释hello变量
HelloWorld
root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo "$hello World" 
Hello World
root@iZuf6ilzd4iqvuj4dvuiwtZ:~#

$符号引入了参数扩展、命令替换或算术扩展。要扩展的参数名称或符号能够用括号括起来,这是可选的,但能够保护变量,使其从能够被解释为名称的一部分的字符中扩展。

参数扩展

${parameter}
              参数的值被替换。当参数是一个超过一个数字的位置参数时,或者在参数后面加上一个不被解释为其名称的部分的字符时,须要使用括号。参数是一个
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH}
                /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter:-word}
              使用默认值,若是parameter未定义或值为空则被替换成word,不然为parmeter的值
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH:-w} #PATH不为空
                /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PAT:-w} # PAT为空
                w
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter:=word}
              给parameter赋值默认值,若是parameter为空或未定义,则将word赋值给parmaeter,不然值不变,parameter的值不变。特殊字符和位置参数不适用
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PAT:=w}
                w
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PAT}
                w
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH:=W}
                /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter:?word}
              若是parameter未定义或为空,则在输出(标准错误)一个错误word,不然输出parameter的值
               列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${P:?ERROR} # P未定义
                -bash: P: ERROR
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter:+word}
              使用替代值.  若是parameter 为空或未定义,输出为空,不然输出word
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${P:+ERROR}

                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH:+ERROR}
                ERROR
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter:offset}
       ${parameter:offset:length}
              子字符串扩展,从offset位置开始,输出length个字符
            若是偏移量计算为小于零的数,则该值用做参数值结束时字符的偏移量。
            若是长度对小于零的数求值,则将其解释为从参数值(而不是多个字符)结
            束字符的偏移量,而扩展是偏移量与结果之间的字符。注意,一个负偏移
            量必须与冒号隔开至少一个空间。
                若是length未指定,则0-offset位置的字符将会被删除
              若是参数是@,那么结果就是长度位置参数开始偏移。相对于最大的位
              置参数,一个负偏移量被取走,因此-1的偏移量等于最后一个位置参数
              。若是长度计算为小于零的数,则为扩展偏差。

              若是参数是由@或*编写的索引数组名,则结果是数组的长度成员以${pa
              rameter[offset]}开始。相对于指定数组的最大索引,将使用一个负偏
              移量。若是长度计算为小于零的数,则为扩展偏差。

              应用于关联数组的子字符串扩展会产生未定义的结果。

              子字符串索引是从零开始的,除非使用了位置参数,在这种状况下,在
              默认状况下,索引从1开始。若是偏移量为0,而且使用了位置参数,$0
              将被预先固定到列表中。
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH:2}
                sr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH:2:4}
                sr/l
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${!prefix*}
       ${!prefix@}
              变量名匹配,匹配以prefix开头的变量名,输出匹配的变量名
              列:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${!P*}
                PAT PATH PIPESTATUS PPID PS1 PS2 PS4 PW PWD
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${!P@}
                PAT PATH PIPESTATUS PPID PS1 PS2 PS4 PW PWD
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${!name[@]}
       ${!name[*]}
              数组键的列表。若是名称是一个数组变量,则扩展到名称中指定的数组
              索引(键)列表。若是名称不是数组,则将其扩展为0,若是名称设置为n
              ull,则为null。当使用@时,扩展出如今双引号,每一个键扩展到一个单独的单词。
                例如:
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${name[@]}
                    1 2
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${!name[@]}
                    0 2
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${#parameter}
              变量长度,若是变量未定义或为空则返回0,若是是一个数组变量则返回数组长度
              例如:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${#PATH}
                60
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter#word}
       ${parameter##word}
              前缀匹配模式,若是parameter的值以word开头则parameter前的word将会被删除,若是parameter是一个数组变量,形如${parameter[@]#word},则此数组中的每一个值将会与word作前缀匹配

              #word 为最短匹配
              ##word 为最长匹配
                例如:
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH#/usr}
                    /local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 
       ${parameter%word}
       ${parameter%%word}
              与${parameter#word}相反,后缀匹配
                例如:
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH%bin}
                    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter/pattern/string}
              模式替换,pttern将被替换成string
              正常状况下pattern 只有第一个匹配的会陪替换成string
              若是表达式以#开头,如:#w,则必须匹配以w开头的
              若是表达式以%几位,如:t%,则必须匹配以t结尾的
              pattern支持通配符*,如:${PWD/*/s},则变量PWD的值所有被替换成s
              若是parameter是一个数组变量,则数组中的成员都会执行此操做,返回一个匹配结果数
                例如:
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${PATH/#\/usr/s}
                    s/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                    root@iZuf6ilzd4iqvuj4dvuiwtZ:~# 

       ${parameter^pattern}
       ${parameter^^pattern}
       ${parameter,pattern}
       ${parameter,,pattern}
              大小写转换.
              ^ 操做将pattern的匹配结果转换成大写字母,第一个字符
              , 操做将pattern的匹配结果转换成小写字母,第一个字符
              ^^ 操做将pattern的匹配结果转换成大写字母
              ,, 操做将pattern的匹配寄过转换成小写字母

              若是parameter是一个数组变量,则数组中的每一个成员将会与pattern作匹配
              通配符:
                * 在^^和,,操做中表示0个或多个字符,在^和,中表示一个或0个字符
                ? 与*相同
             例如:
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${TERM,*} 
                xterm
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${TERM^*} 
                Xterm
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${TERM^^*} 
                XTERM
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~# echo ${TERM,,*} 
                xterm
                root@iZuf6ilzd4iqvuj4dvuiwtZ:~#

参考资料

相关文章
相关标签/搜索