变量
变量是能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。
变量声明
声明变量一般使用下面方式:
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有两种变量:
-
shell局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 通过赋值语句定义好的变量,可以通过如下方法定义shell变量 root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# declare var1=123 root@iZuf6ilzd4iqvuj4dvuiwtZ:~/HtmlDOM/Libs# var1=123
-
用户环境变量 所有的程序,包括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(全局)变量。
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:~#
变量调用
在声明变量一个变量时变量名称要遵守下列规则:
- 不能以特殊字符(除了_),数字,美元符($)开头
- 变量名不能是纯数字
- 变量名可以是英文或数字或特殊字符(_)的组合
调用变量时在变量明前面以$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:~#