shell $() $(()) $[] $[[]] ${} 使用语法
一、 $() 与``命令的替换含义$( )和` `表示"命令的替换",在编写脚本过程中尽量使用$( )来进行命令替换在shell中fork一个子进程区做他们括起来的命令,然后在返回父进程实例[root@zxp1 ~]# echo date//直接当成字符串输出date[root@zxp1 ~]# echo `date`//相当于函数调用,先执行date命令Tue Sep 3 16:10:43 CS
文章目录
一、 $() 与``命令的替换
- 含义
$( )和 ` ` 表示"命令的替换"
原理:将对反引号或$()里的内容先进行执行,然后将执行的结果代换到当前命令中
在shell中fork一个子进程区做他们括起来的命令,然后在返回父进程
在编写脚本过程中尽量使用$( )来进行命令替换,理由如下:
🎈 ` `很容易与''搞混乱,尤其对初学者来说。
🎈 在多层次的复合替换中,` `必须要额外的转义字符处理(反斜线),而$( )比较直观。
🎈 $( )的弊端是,并不是所有的类unix系统都支持这种方式,但反引号是肯定支持的。
- 实例
[bob@centos home]$ echo date //直接当成字符串输出
date
[bob@centos home]$ echo `date` //相当于函数调用,先执行date命令
Tue Sep 3 16:10:43 CST 2019
[bob@centos home]$ echo $(date) //作用与上面的命令一样,但不是所有版本的linux系统都支持
Tue Sep 3 16:11:45 CST 2019
命令嵌套
[bob@centos home]$ echo $(echo $(date))
Tue Sep 3 16:10:43 CST 2019
[bob@centos home]$ echo `echo `date``
date
[bob@centos home]$ echo `echo \`date\``
Tue Sep 3 16:10:43 CST 2019
二、${ } 变量替换
1、含义
🎈一般情况下,$var与${var}是没有区别的,但是用${ }会比较精确的界定变量名称的范围
例如:
[root@localhost ~]# A=Linux
[root@localhost ~]# echo $AB #表示变量AB
[root@localhost ~]# echo ${A}B #表示变量A后连接着B
LinuxB
🎈${ }内部还支持"变量替换"、"变量截取"、"变量删除"
2、变量替换
- 变量替换含义
变量替换可以根据变量的状态(空值、非空值)来改变它的值
- 变量替换形式
形式 | 说明 |
---|---|
${var} | 变量本来的值 |
${var:-word} | 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 |
${var:=word} | 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。是一种赋值默认值的常见做法 |
${var:?word} | 如果变量 var 为空或已被删除(unset),那么将消息word 送到标准错误输出,可利用此特性来检查是否设置了变量的值。若此替换出现在Shell脚本中,那么脚本将停止运行。 |
${var:+word} | 如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
(1)${var:-word}
若 var为空或未设置,返回默认值但是并不把默认值赋值给该变量,若 var 不为空,则不替换,var 的值不变
[Neptuneyt]$ var=
[Neptuneyt]$ echo ${var:-word}
word
[Neptuneyt]$ echo $var #此时,变量依旧为空
(2) ${var:=word}
若var为空或未设置,把默认值赋值给该变量。若 var设置了,则不替换,var的值不变
[Neptuneyt]$ var=
[Neptuneyt]$ echo ${var:=word}
word
[Neptuneyt]$ echo $var
word
(3) ${var:+word}
若 var 不为空时,返回默认值,并且也不重新赋值。
[Neptuneyt]$ var=number
[Neptuneyt]$ echo ${net:+word}
word
[Neptuneyt]$ echo $var #不改变变量原值
number
举个例子:
#!/bin/bash
echo "======================="
echo " 目前的版本有: "
echo " mysql-8.0"
echo " mysql-5.7"
echo " 默认版本为: MySQL-8.0"
echo "======================="
read -p "请输入你要选择的版本" Num
Num=`echo ${Num:=8.0}`
echo "您选择的版本为$Num,稍后给你安装......"
3、变量截取
指定位置截取字符串
语法:
${变量名:起始位置:长度} 从哪里截取留那里
[root@linux-server ~]# a=12345678
[root@linux-server ~]# echo ${a:5} #从左往右第5位开始截取,留下后三位
678
[root@linux-server ~]# echo ${a:3:4} #从第3位开始截取,留下后四位的,剩下的都不要。
4567
[root@linux-server ~]# echo ${a:2:-1} #从左往右第2位开始截取,从右往左截取第一位
34567
[root@linux-server ~]# echo ${a:2:-2}
3456
实例:
[root@localhost ~]# vim test11.sh
#!/usr/bin/bash
read -s -p "请输入您的11位手机号 " phone
echo
echo "你的手机号是 $phone"
echo "手机号后四位是 ${phone:7}"
4、匹配删除
语法:
#*chr
表示删除从左到右第一个遇到的字符chr及其左侧的字符##*chr
表示删除从左到右最后一个遇到的字符chr及其左侧的字符(贪婪模式)%chr*
表示删除从右向左第一个遇到的字符chr及其右侧的字符%%chr*
表示删除从右到左最后一个遇到的字符chr及其右侧的字符(贪婪模式)
在键盘上,#在$ 符的左边,%号在$符的右边,为了便于记忆,大家因此可以记住 # 删除左边字符,%删除右边字符
参数解释:
项目 | Value |
---|---|
* | 表示全部字符 |
% | 最短尾匹配 |
%% | 最大尾匹配 |
% | 从右往左 |
# | 从左往右 |
实例:
[root@newrain ~]# echo ${url#*.} 从前往后匹配到“.”最短匹配
sina.com.cn
[root@newrain ~]# echo ${url##*.} 从前往后匹配到“.”,最长匹配
cn
[root@newrain ~]# echo ${url%.*} 从后往前匹配到“.”,最短匹配
www.sina.com
[root@newrain ~]# echo ${url%%.*} 从后往前匹配到“.”,最长匹配
www
[root@newrain ~]# echo ${url#a.} #不加*
www.sina.com.cn
[root@newrain ~]# echo ${url#*a.} #加*
com.cn
file=/dir1/dir2/dir3/my.file.txt
我们可以用 ${ } 分别替换获得不同的值:
${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
三、$ [] 与$(()) 整数运算
它们是一样的,都是进行数学运算的。支持+ - * / %:分别为 “加、减、乘、除、取模”。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的。
例:
$ a=5; b=7; c=2
$ echo $(( a+b*c ))
19
$ echo $(( (a+b)/c ))
6
$ echo $(( (a*b)%c))
1
在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用,如:
$(( $a + $b * $c))
19
四、[ ] 判断符号
即为test命令的另一种形式。
单中括号 []
-
bash 的内部命令,[和test是等同的。如果我们不用绝对路径指明,通常我们用的都是bash自带的命令。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试,并且根据比较的结果来返回一个退出状态码。if/test结构中并不是必须右中括号,但是新版的Bash中要求必须这样。
-
Test和[]中可用的比较运算符只有
==和!=
,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用,对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab \ < bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a 和-o 表示。 -
字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。
-
在数组中,中括号用来引用数组中每个元素的编号。下标
注意:
- 在括号两边各加一个空格,否则会报错。
- test命令使用标准的数学比较符号来表示字符串的比较,而用文本符号来表示数值的比较。(数值比较:-eq、-gt)(字符串比较:)
- 大于符号或小于符号必须要转义,否则会被理解成重定向。
五、(( ))与[[ ]]
它们分别是[ ]的针对数学比较表达式
和字符串表达式
的加强版。
1、双小括号 (( ))
整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。
只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)
单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6
常用于算术运算比较,双括号中的变量可以不使用 $ 符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合C语言运算规则, 比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in ` seq 0 4 `或者for i in {0…4}。 再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]
2、双中括号[[ ]]
[[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
使用[[ … ]]条件判断结构,而不是[ … ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。 比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
六、()与{}的区别
相同点:
- ()和{}都是把一串的命令放在括号里面,如果命令在一行,则命令之间用
;
隔开
不同点:
- ()只是把一串命令重新开一个子shell进行执行,不影响当前shell环境;{}对一串命令在当前shell执行,影响当前shell环境
- ()最后一个命令不用分号,{}最后一个命令要用分号
- ()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必要要有一个空格
- ()和{}中括号里面的某个命令的重定向只影响改名了,但括号外的重定向则影响到括号里的所有命令
[root@bogon t]# var=test
[root@bogon t]# echo $var
test
[root@bogon t]# (var=notest;echo $var)
notest
[root@bogon t]# echo $var
test
[root@bogon t]# { var=notest;echo $var;}
notest
[root@bogon t]# echo $var
notest
七、==与=的区别
== 可用于判断变量是否相等,= 除了可用于判断变量是否相等外,还可以表示赋值。
= 与 == 在 [ ] 中表示判断(字符串比较)时是等价的
[root@manager day5]# s1="foo"
[root@manager day5]# s2="foo"
[root@manager day5]# [ $s1=$2 ] && echo "equal"
equal
[root@manager day5]# [ $s1==$2 ] && echo "equal"
equal
在 (( )) 中 = 表示赋值, == 表示判断(整数比较),它们不等价
[root@manager day5]# ((n=5))
[root@manager day5]# echo $n
5
[root@manager day5]# ((n==5)) && echo "equal"
equal
补充:
=~支持正则表达式,同时支持变量比较相等。==只能支持比较变量相不相等。
可知:如果需要做两个变量的包含关系,可以使用=~匹配
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)