shell中各种括号(),[],(()),[[]],{}等的作⽤⼤全及⽰例
⽂章⽬录
⼀、()
1、命令组
连接多个命令组,⽤;隔开,最后⼀个命令后;可加可不加。括号中的命令会新开⼀个⼦shell顺序执⾏,所以⾥⾯的操作对括号外主进程⽆关。
a=0
(a=1;b=2;echo$a)# ⼦进程内输出a为1
shell代码echo$a# 主进程,输出a为0
2、命令替换
格式为 $(command),相当于 `command`。shell遇到此格式,会先执⾏ command 命令,得到标准输出,再将此输出放回到原来命令。
SCRIPTPATH=$(dirname $0)# sh脚本的相对⽬录
3、初始化数组
Shell 数组⽤括号来表⽰,元素⽤"空格"符号分割开。
array=(a b c)
echo${array[1]}# 输出b
⼆、(())
1、C语⾔规则运算
表达式 $((exp)),其中exp只要符合C语⾔规则的运算符即可,包括加减乘除、+=、<=、>=等。
进⾏不同进位(如⼆进制、⼋进制、⼗六进制)运算时,输出结果会全都⾃动转化成⼗进制。
echo$((2*2+(1-2)))# 输出3
a=1
echo$((a++))# 输出2,且从此之后a=2
echo$((2#10+4))# 输出6,在10前⾯的2#表⽰这是个⼆进制
echo$((a<2))# 输出1。如果为假,则输出0。
2、重定义变量值
在((exp))中可以对变量进⾏定义或重新赋值,且之后脚本全部有效(不是像()那样只在⼦进程有效)。
a=1
((a=2))
echo$a# 输出2
3、算术⽐较
在((exp))中可以进⾏算术⽐较(不能进⾏字符串⽐较),双括号中的变量可以省略$符号前缀,当然也可以带着。
a=1
((a==1))&&echo"true"# 输出 true
(($a==1))&&echo"true"# 输出 true
三、[]
1、条件判断
[] 本质上是 test 语句,[是调⽤test的命令标识,]是关闭条件判断,如:
a="abc"
if[ -n "$a"];then echo"true";fi# 输出true,注意[]内-n或者-z时字符串两边必须加上双引号
if test -n "$a";then echo"true";fi# 输出true,注意test内-n或者-z时字符串两边必须加上双引号
2、字符范围
⽤作正则表达式的⼀部分,描述⼀个匹配的字符范围,如删除⼀个字符串中的所有数字:
echo"ap1p23le"|tr -d "[0-9]"# 输出 apple
echo[a-b].txt # 输出:a.,前提是两个⽂件都存在。
# 但是如果当前路径只存在a.txt或b.txt,则只会输出存在的⽂件。
# 如果两个⽂件均不存在,则输出固定字符串:[a-b].txt
3、数组下标
在⼀个array后,作为引⽤数组元素的下标,如
a=(1 2 3)
echo${a[0]}# 输出:1
echo${a[*]}# 输出:1 2 3
四、[[]]
1、条件判断
使⽤[[]]条件判断结构,与[]有以下区别:
本质上,[]和test是命令,⽽[[]]是关键字,所以重定向等字符在[]中会被认为成重定向,⽽在[[]]中是⽐较符号的意思。
&&、||、<;和> 操作符能够正常存在于[[]]条件判断结构中,但是如果出现在[]结构中的话,会报错。⽐如可以直接使⽤if [[ $a != 1 && $a != 2 ]], 如果不使⽤双括号, 则为if [ $a != 1] && [ $a != 2 ]或者if [ $a != 1 -a $a != 2 ]
[[]]⽀持字符串的模式匹配,[]不⽀持。使⽤=或==进⾏字符串⽐较,等号右边的可以作为⼀个模式,⽐如[[ "hello" == hell? ]]为真。模式匹配不能加引号,否则会作为固定字符串,如[[ "hello" == "hell?" ]]为假。
[[]]⽀持算术扩展,⽽[]不⽀持。如if [[ 1+2 -eq 3 ]],⽽if [ 1+2 -eq 3 ]则会报错。
2、返回状态码
本质上,bash把[[]]中的表达式看作⼀个单独的元素,并返回⼀个退出状态码。
⽐如:
[[ 1 -gt 0 ]]
echo$?# 输出0
[[ 1 -gt 2 ]]
echo$?# 输出1
可以看到,如果[[]]内的表达式为真,则返回退出码0,这也是其他所有命令执⾏正常时所返回的退出码。
因此,如果⽤[[]]作为if的判断条件,道理是和判断⼀个命令或函数是否顺利执⾏是⼀样的。
五、{}
1、字符扩展
{}可以作为通配符进⾏扩展,有两种⽤法:
echo {a,b}.txt 输出a.。与echo [a-b].txt区别在于,后者只输出存在的⽂件名,⽽前者不管是不是存在此⽂件,永远都会输出a.txt
<,因为{}的字符扩展和是不是⽂件名没有关系。
echo {a..c}.txt输出a. c.txt。
这两种扩展也可以⽤于循环:
$ for i in{0,2};do echo$i;done
2
$ for i in{0..2};do echo$i;done
1
2
2、代码块
⼜被称为内部组,格式为{ cmd1;cmd2;},这个结构事实上创建了⼀个匿名函数 。
{}与()都可以执⾏⼀连串命令,区别如下:
()会新开⼀个⼦进程,括号内命令与括号外⽆关。{}内的命令不会新开⼀个⼦进程运⾏,即脚本余下部分仍可使⽤括号内变量。
两者括号内的命令间都要⽤;隔开,但()最后⼀个命令的分号可有可⽆,但{}最后⼀个也必须有分号。
{}的第⼀个命令和左括号{之间必须要有⼀个空格(右括号}⽆此要求),⽽()两个括号的空格均可有可⽆。
3、特殊替换结构
有4种特殊的替换结构:${var:-string},${var:+string},${var:=string},${var:?string}
(1)${var:-string}表⽰若变量var不为空,则等于var的值,否则等于string的值。
⽐如:
a=''
b="bbb"
echo${a:-foo}# 输出:foo
echo ${a:-"foo"}# 输出:foo
echo${a:-$b}# 输出:bbb
(2)${var:=string}的替换规则与${var:-string}相同,不过多了⼀步操作:若var为空时,还会把string的值赋给var。
⽐如:
a=''
b="bbb"
echo${a:=$b}# 输出:bbb
echo$a# 输出:bbb
(3)${var:+string}的替换规则和上⾯的相反,表⽰若变量var不为空,则等于string的值,否则等于var的值(即空值)。
⽐如:
a=""
b="bbb"
echo ${a:+"foo"}# 输出为空
echo ${b:+"foo"}# 输出:foo
(4)${var:?string}表⽰若变量var不为空,则等于var的值,否则把string输出到标准错误中,并从脚本中退出。
我们可利⽤此特性来检查是否设置了变量的值,⽐如⼀个脚本test.sh内容如下:
#!/bin/bash
a=""
b="bbb"
echo ${a:?"warn:string is null"}
echo ${b:?"warn:string is null"}
echo"done"
然后在命令⾏中执⾏命令:
$ sh test.sh > out.log 2> err.log # 标准输出⾄out.log,标准错误输出⾄err.log
$ cat out.log
aaa
$ cat err.log
test.sh: line 5: b: warn:string is null
可以看到,out.log中没有done,因此脚本执⾏到Line 5的错误就提前退出了。
4、模式匹配截断
有4种模式:${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
(1)${var%pattern}表⽰看var是否以模式pattern结尾,如果是,就把var中的内容去掉右边最短的匹配模式。
(2)${var%%pattern}表⽰看var是否以模式pattern结尾,如果是,就把var中的内容去掉右边最长的匹配模式。
(3)${var#pattern}表⽰看var是否以模式pattern开始,如果是,就把var中的内容去掉左边最短的匹配模式。
(4)${var##pattern}表⽰看var是否以模式pattern开始,如果是,就把var中的内容去掉左边最长的匹配模式。
⽐如:
a="apple"
echo ${a%"le"}# 去掉右边固定"le",输出:app
echo${a%p*}# 去掉右边最短匹配,输出:ap
echo${a%%p*}# 去掉右边最长匹配,输出:a
echo ${a#*p} # 去掉左边最短匹配,输出:ple
echo ${a##*p} # 去掉左边最长匹配,输出:le
5、长度截断
有2种模式:${var:num},${var:num1:num2}
(1)${var:num}表⽰提取var中第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使⽤在冒号后⾯加空格或⼀个数字或整个num加上括号,如${var: -2}、${var:1-3}或${var:(-2)}。
(2)${var:num1:num2}表⽰从var中第num1个位置开始提取长度为num2的⼦串。num1从0开始。
⽐如:
a="apple"
echo${a:2}# 去掉前2个,输出:ple
echo${a: -2}# 保留后2个,输出:le
echo${a:1:3}# 保留从1开始的3个字符,输出:ppl
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论