一、$( ) 与 ` ` (反引号) ######################################################################################################################## 在Shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换用的。 命令替换:就是完成()或反引号里的命令行,然后将其结果替换出来,再重组命令行。 例如: [root@ss-server ~] # echo "this is $(date +%Y-%m-%d)" this is 2020-01-08 [root@ss-server ~] # echo "this is `date +%Y-%m-%d`" this is 2020-01-08 ###### 使用 $( ) 的理由 ###### 1)` ` 反引号很容易与 ' ' 单引号搞混乱; 2)在多层次的复合替换中,` `反引号须要额外的跳脱( \` )处理,而 $( ) 则比较直观; 比如命令:command1 `command2 `command3` ` 原本的意图: 是要在 command2 `command3` 中先将 command3 提换出来给 command 2 处理,然后再将结果传给 command1 `command2 …` 来处理。 然而,真正的结果: 在命令行中却是分成了 `command2 ` 与 '' 两段。 小示例: 使用多层次的``反引号 [root@ss-server ~] # echo `echo `date +%Y-%m-%d`` date +%Y-%m-%d 换成 $( ) 就没问题了,做多少层的替换都没问题! [root@ss-server ~] # echo $(echo $(date +%Y-%m-%d)) 2020-01-08 ###### $( ) 的不足 ###### $( ) 并不见的每一种 shell类型都能使用,如果使用 bash2 的话,肯定没问题。 二、${ } 用来作变量替换 ######################################################################################################################## 一般情况下,$var 与 ${var} 并没有什么不一样。但是用 ${ } 会比较精确的界定变量名称的范围! 如下: [root@ss-server ~] # a=b [root@ss-server ~] # echo $ab [root@ss-server ~] # echo ${a}b bb 原本是打算先将 $a 的结果替换出来,然后再补一个 b 字母于其后, 但在命令行上,真正的结果却是只会提换变量名称为 ab 的值出来,结果没有ab的变量,结果就为空了! 若使用 ${ } 就没问题。 再注意区分下面的情况:即设置变量,以 = 左边的为变量名,如以右边为变量名则无效! [root@ss-server ~] # a=b [root@ss-server ~] # echo ${b} [root@ss-server ~] # echo ${a} b [root@ss-server ~] # echo $a b b b [root@ss-server ~] # echo ${a}${b} b [root@ss-server ~] # echo ${a}${a} bb [root@ss-server ~] # echo ${b}${b} [root@ss-server ~] # ###################################################################### 下面开始介绍下${ } 的一些高阶功能 先定义一个变量,下面示例都是以给变量做说明: [root@ss-server ~] # file=/dir1/dir2/dir3/my.file.txt 1)可以用 ${ } 分别替换获得不同的值 --------------------------- 使用 #和%进行截取字符串的方法在文章上面已经详细介绍了,这里就不做过多说明了。 ${ file #*/}: 表示删除掉第一条 / 及其左边的字符串,即结果为:dir1/dir2/dir3/my.file.txt ${ file ##*/}: 表示删除掉最后一条 / 及其左边的字符串,即结果为:my.file.txt ${ file #*.}: 表示删除掉第一个 . 及其左边的字符串,即结果为:file.txt ${ file ##*.}: 表示删除掉最后一个 . 及其左边的字符串,即结果为:txt ${ file %/*}: 表示删除掉最后一条 / 及其右边的字符串,即结果为: /dir1/dir2/dir3 ${ file %%/*}: 表示删除掉第一条 / 及其右边的字符串,即结果为:(空值) ${ file %.*}: 表示删除掉最后一个 . 及其右边的字符串,即结果为: /dir1/dir2/dir3/my . file ${ file %%.*}: 表示删除掉第一个 . 及其右边的字符串,即结果为: /dir1/dir2/dir3/my 关于上面使用 # 和 % 的记忆方法为: # 是删除掉指定字符串左边的! % 是删除掉指定字符串右边的! 单一符号是最小匹配﹔两个符号是最大匹配 #*str 是删除掉第一个str及其左边的内容; ##*str 是删除掉最后一个str及其左边的内容; %str* 是删除掉最后一个str及其右边的内容;%%str* 是删除掉第一个str及其右边的内容! 下面的截图字符串的方法在文章上面已经详细介绍了,这里就不做过多说明了。 ${ file :0:5}: 表示提取最左边的5个字节,即结果为: /dir1 ${ file :5:10}: 表示提取第5个字节右边的连续10个字节,即结果为: /dir2/dir3 如下脚本示例: [root@bzacbsc01ap2001 ~] # hostname bzacbsc01ap2001 主机名中第3到第6字符是本机的业务模块名称,也就是cbs。下面脚本中的表示从a字符串左边的第4个字符开始截取,截取3个字符(即3:3) [root@bzacbsc01ap2001 ~] # cat test.sh #!/bin/bash a=$( hostname ) b=${a:3:3} APP=$( echo ${b}) echo "本机tomcat的安装目录为: /opt/${APP}/tomcat" 执行结果为: [root@bzacbsc01ap2001 ~] # sh test.sh 本机tomcat的安装目录为: /opt/cbs/tomcat 2)可以使用 ${ } 对变量值里的字符串作替换 --------------------------- ${ file /dir/path }: 表示将第一个 dir 提换为 path,即结果为: /path1/dir2/dir3/my . file .txt ${ file //dir/path }:表示将全部 dir 提换为 path,即结果为: /path1/path2/path3/my . file .txt 如下示例: [root@ss-server ~] # Test_Name=kevin/bo/AnHui [root@ss-server ~] # Test_Path=${Test_Name.} #使用//将变量中所有的/替换为. [root@ss-server ~] # echo ${Test_Path} kevin.bo.AnHui [root@ss-server ~] # Test_Path=${Test_Path/.//} #使用/将变量中第一个.替换为/ [root@ss-server ~] # echo ${Test_Path} kevin /bo .AnHui [root@ss-server ~] # Test_Path=$(echo $Test_Path | tr '[A-Z]' '[a-z]') [root@ss-server ~] # echo ${Test_Path} kevin /bo .anhui 可以在shell脚本中进行变量的多次替换,如下: [root@ss-server ~] # vim test.sh #!/bin/bash MODULE_NAME=$1 ......... # image信息 IMAGE_PATH=${MODULE_NAME
.} IMAGE_PATH=${IMAGE_PATH/. // } IMAGE_PATH= "$IMAGE_PATH.$BRANCH.$SERVICE_NAME" IMAGE_PATH=$( echo $IMAGE_PATH | tr '[A-Z]' '[a-z]' ) TAG=${REVISION:0:7} ......... 3)使用 ${ } 还可以针对不同的变量状态赋值 (没设定、空值、非空值) --------------------------- ${ file -my. file .txt}: 表示假如 $ file 没有设定,则使用 my. file .txt 作传回值。(空值及非空值时不作处理) ${ file :-my. file .txt}: 表示假如 $ file 没有设定或为空值,则使用 my. file .txt 作传回值。 (非空值时不作处理) ${ file +my. file .txt}: 表示假如 $ file 设为空值或非空值,均使用 my. file .txt 作传回值。(没设定时不作处理) ${ file :+my. file .txt}: 表示假如 $ file 为非空值,则使用 my. file .txt 作传回值。 (没设定及空值时不作处理) ${ file =my. file .txt}: 表示假如 $ file 没设定,则使用 my. file .txt 作传回值,同时将 $ file 赋值为 my. file .txt 。 (空值及非空值时不作处理) ${ file :=my. file .txt}: 表示假如 $ file 没设定或为空值,则使用 my. file .txt 作传回值,同时将 $ file 赋值为 my. file .txt 。 (非空值时不作处理) ${ file ?my. file .txt}: 表示假如 $ file 没设定,则将 my. file .txt 输出至 STDERR。 (空值及非空值时不作处理) ${ file :?my. file .txt}: 表示假如 $ file 没设定或为空值,则将 my. file .txt 输出至 STDERR。 (非空值时不作处理) ${1:-NULL} 表示是当$1为空时,自动将NULL替换成$1所要带入的变量值。 ${2:-NULL} 表示是当$2为空时,自动将NULL替换成$2所要带入的变量值。 例如: [root@ss-server ~] # kevin=123 [root@ss-server ~] # echo ${kevin+anhui} anhui [root@ss-server ~] # echo ${haha:=null} #haha变量没有设定,则使用=后面的null作为传回值 null 也可以在shell脚本中进行变量的状态赋值 [root@ss-server ~] # vim test.sh #!/bin/bash ......... AFS_ENV=${AFS_ENV:=null} AFS_APPID=${AFS_APPID:=null} AFS_CLUSTER=${AFS_CLUSTER:=null} AFS_JARNAME=${AFS_JARNAME:=null} ......... 对于上面的理解,在于一定要分清楚 unset 与 null 及 non-null 这三种赋值状态。 一般而言, : 与 null 有关, 若不带 : 的话, null 不受影响, 若带 : 则连 null 也受影响! [root@ss-server ~] # kevin=123 [root@ss-server ~] # echo ${kevin:+anhui} anhui [root@ss-server ~] # kevin= [root@ss-server ~] # echo ${kevin:+anhui} [root@ss-server ~] # unset kevin [root@ss-server ~] # echo ${kevin:+anhui} [root@ss-server ~] # 使用${ #var}可以计算出变量的长度 [root@ss-server ~] # echo ${file} /dir1/dir2/dir3/my . file .txt [root@ss-server ~] # echo ${#file} 27 三、 bash 的组数(array)处理方法 ######################################################################################################################## 一般而言,A= "be sh se cho" 这样的变量只是将 $A 替换为一个单一的字符串, 但是改为 A=(be sh se cho) ,则是将 $A 定义为组数,所以说数组定义需要使用()括号!! 关于数组的使用,之前已经在 https: //www .cnblogs.com /kevingrace/p/5761975 .html 这篇文章中详细介绍了,这里简略说下: 组数常用的几个替换方法: ${A[@]} 或 ${A[*]} 表示获得全部组数,即得到be sh se cho 。 ${A[0]} 表示获得数组中的第1个组数。同理,${A[1]} 获得的是第2个组数。 ${ #A[@]} 或 ${#A[*]} 表示获得全部组数数量。 ${ #A[0]} 表示获得第一个组数的长度,即be的长度,为2; 同理,${#A[3]} 表示获得第四个组数的长度,即cho的长度,为3; A[1]=haha 表示将第2个组数重新定义为haha; 同理,A[3]=heihei 表示将第4个组数重新定义为heihei; 四、$(( )) 用途:用来作整数运算 ######################################################################################################################## 在 bash 中,$(( )) 的整数运算符号大致有这些: + - * / 分别表示为 "加、减、乘、除" 。 % 表示余数运算 & | ^ ! 分别表示分别为 "AND、OR、XOR、NOT" 运算。 例如: [root@ss-server ~] # a=6;b=7;c=8 [root@ss-server ~] # echo $(( a+b*c )) 62 [root@ss-server ~] # echo $(( (a+b+3)/c )) 2 [root@ss-server ~] # echo $(( (a*b)%c)) 2 使用$[]、 let 、$(()) 都可以作为整数运算,效果是一样的! [root@ss-server ~] # echo $((4*9)) 36 [root@ss-server ~] # echo $[4*9] 36 [root@ss-server ~] # let a=4*9 [root@ss-server ~] # echo $a 36 [root@ss-server ~] # let "a=4*9" [root@ss-server ~] # echo $a 36 [root@ss-server ~] # let a="3+5" [root@ss-server ~] # echo $a 8 [root@ss-server ~] # a=18 [root@ss-server ~] # let a++ [root@ss-server ~] # echo $a 19 事实上,单纯用 (( )) 也可重定义变量值。 (( )) 这组符号的作用与 let 指令相似,用在算数运算上,是 bash 的内建功能。所以,在执行效率上会比使用 let 指令要好许多。 [root@ss-server ~] # a=10; ((a++)) [root@ss-server ~] # echo ${a} 11 [root@ss-server ~] # cat test.sh #!/bin/bash (( a = 10 )) echo -e "inital value, a = $a\n" (( a++)) echo "after a++, a = $a" [root@ss-server ~] # sh test.sh inital value, a = 10 after a++, a = 11 转载于: https://www.cnblogs.com/kevingrace/p/5896386.html |