【学习笔记】shell高级变量(变量扩展、命令替换、算术扩展)之变量扩展
在bash shell中,$算符会触发3种扩展。基本形式如下表:
基本型 | 扩展种类 | 范例 |
${变量名称} | 变量扩展 | ${filename} |
$(命令) | 命令扩展 | $(ls /} |
$((算术式)) | 算术扩展 | $((9+9)) |
变量扩展:变量扩展是一种简易的条件判断,对不同的条件赋予变量不同的替换值。
变量扩展是对基本型加上条件判断,如若条件符合(如不存在或空值),则进行变量替换,若不符合,则有相应的做法。是一种隐士的if -then -else.
测试变量“存在”与否的基本用法
语法:${待测变量-默认值} 判断条件:若变量不存在,则符合条件,以传回默认值作为处置。
测试变量”不存在“或其值为空:传回一个默认值:
语法:${待测变量:-默认值} 判段条件:若变量不存在或为空,则符合判断,以传回默认值作为处置
这两种变量扩展的测试,差别仅在于:除了存在性,待测变量是否要再判断它是否为空值,而在使用的符合上则多了:(冒号)
若变量扩展的条件式只有-这个符合,则变量只做“存在性”判断
若变量扩展的条件试使用:-这个符号,除了判断变量的“存在性”之外,也回多加一个判断:变量是否为空值。
变量扩展${变量名称:-默认值}的主要用途:在script中,这个变量一定要有值才行。因此,变量扩展的结果。一定要传回一个非空值。
特殊用法:前述变量扩展的语法经常用在script的开头,如 [ -n ${DEBUG:-} ] && set -v
[]是测试条件的语法,其中,-n是用来测试后接的变量是否有值,若非空,则传回真值。
${DEBUG:-}原本应防止默认值的地方却没有任何值,表示故意要让默认值为空值。
这样做的目的是:如果变量DEBUG非空值,那么[-n]条件测试就会成立,接着执行逻辑AND,
于是脚本进入查错模式;如果变量DEBUG没有设置或者为空,则变量扩展的结果为空值。因此[-n]的条件测试就不成立。逻辑
AND的下一个指令就不再执行,查错的功能就没有打开。
测试变量”不存在“或其值为空,给变量设一个默认值
语法:${待测变量:=默认值} 判断条件:若变量不存在或其值为空,则符合判断。
用途:目的:给变量设置一个默认值。
测试变量是否“不存在”或其值为空:提示错误信息
语法:${待测变量:?提示信息} 判断条件:若变量不存在或空值,则符合判断。
用途:确保其变量值一定要存在,否则若继续执行下去,恐怕会发生严重后果。
测试变量的“存在性”
语法:${待测变量:+真值} 判断条件:若变量存在且其值非空,则符合判断。
用途:用来测试某时间是真的。${1+"$@"}意思是:若$1存在,则传回所有参赛 $@。
记忆法:
: 空 测空值
- 负 测不存在
= 设值 给空值设置一个默认值
? 有问题 检查条件是否完毕后再来执行
+ 正向 , 测试存在。
变量扩展:取字符串切片、字符串长度:
取字符串切片:
语法1:${变量:位置起点} 由指定的位置开始,截取子字符串到字符串结束。
语法2:${变量:位置起点:长度} 由指定位置开始,截取指定长度的子字符串。
计算字符串长度:
语法:${#变量名称}传回变量值的字符串长度。
其他计算字符串长度的方法:
1、expr length "字符串"
2、expr "字符串" : '.*' :符号两边需由空格。
${#变量名称} 计算字串串长度
${#数组[@]} 取得数组元素个数
${#数组[*]} 取得数组元素个数。
变量扩展:对比样式:
目的:是像截取变量值(字符串)的某一部分,将符合样式的部分字符串删除或取代
由字符串前面对比,删除相符者:
由前面对比,删除最短的:语法:${变量#样式} 由最左边(前面)开始,对比变量值,删除“最短想符合的字符串”
例如:filename="/usr/sbin/ntpdate"
r=${filename#/*/} /*/的意思是:凡一对斜线之间有字符串者(空字符串亦可),对比符合。
因#表示由前面取最短的,所以,对比到最短的字符串是/usr/,故将它删除去,然后,传回剩下的字符串.
由前面对比,删除最长的:语法:${变量##样式} 由最左边开始,对比变量值,删除“最长相符的字符串”
由字符串后面对比,删除相符者:
由后面对比,删除最短的 语法:${变量%样式}:
filename="/usr/sbin/ntpdate"
${filename%/*} /*的意思是:凡斜线后有字符串者(空字符串亦可),对比符合。
由后面对比、删最长的 语法:${变量%%样式}
filename="www.baidu.com"
${filename%%.*} .*的意思是:凡.后由字符串着(空字符串亦可)对比符合。
记忆法:
#经常放在数字前面表示前面,所以看到它,就记得它是由前面对比。一个#表示最短,两个#表示最长
%经常放在数字后面代表百分比,所以就记它是由后面对比。一个%最短,%%最长
取代或删除部分字符串
只替换第一个对比符合的字符串: 语法:${变量/样式/替换字符串}
若变量中,有符合样式的字符串(去最长的),则使用替换字符串予以取代。
替换全部对比符合的字符串 语法:${变量//样式/替换字符串}
若变量中,有符合样式的字符串(取最长的),则使用替换字符串全部予以替换。
把对比符合的字符串删除:
只删除一个: 语法:${变量/样式/} 删除第一个符合样式的字符串。
删除全部: 语法:${变量//样式/} 删除所有符合样式的字符串。
要求样式在句首或句尾
在对比样式的时候,若在样式前加上#,则该样式要出现在变量值的开头才算符合。
若在样式前加上%,则该样式要出现在变量值的结尾才算符合。
取变量名称列表,数组索引列表:
取变量名称列表: 语法:${!开头字符串@} 或 ${!开头字符串*}
把所有以指定字符串开头的变量名称列出,各变量之间,使用$IFS定义的第一个分隔符(空格)隔开。
去数组索引列表:语法:${!数组变量[@]} 或${!数组变量[*]} ........bash3.0以上支持。一些不支持。
把数组变量所有的索引列出,各索引值之间,用$IFS第一的第一个分隔符(空格)隔开。
命令扩展:
算术扩展: