共计 5504 个字符,预计需要花费 14 分钟才能阅读完成。
一、小括号,圆括号()
1、单小括号 ()
①命令组。括号中的命令将会新开一个子 shell 程序执行,所以括号中的变量不可能被脚本余下的局部应用。括号中多个命令之间用分号隔开,最初一个命令能够没有分号,各命令和括号之间不用有空格。
②命令替换。等同于 cmd
,shell 扫描一遍命令行,发现了构造,便将(cmd) 构造,便将 (cmd) 中的 cmd 执行一次,失去其规范输入,再将此输入放到原来命令。有些 shell 不反对,如 tcsh。
③用于初始化数组。如:array=(a b c d)
2、双小括号 (())
①整数扩大。这种扩大计算是整数型的计算,不反对浮点型。((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++)), 如果不应用双括号, 则为 foriin‘seq04‘或者 foriin0..4。再如能够间接应用 if((i<5)), 如果不应用双括号, 则为 if [$i -lt 5]。
二、中括号,方括号[]
1、单中括号 []
①bash 的外部命令,[和 test 是等同的。如果咱们不必绝对路径指明,通常咱们用的都是 bash 自带的命令。if/test 构造中的左中括号是调用 test 的命令标识,右中括号是敞开条件判断的。这个命令把它的参数作为比拟表达式或者作为文件测试,并且依据比拟的后果来返回一个退出状态码。if/test 构造中并不是必须右中括号,然而新版的 Bash 中要求必须这样。
②Test 和 [] 中可用的比拟运算符只有 == 和!=,两者都是用于字符串比拟的,不可用于整数比拟,整数比拟只能应用 -eq,-gt 这种模式。无论是字符串比拟还是整数比拟都不反对大于号小于号。如果切实想用,对于字符串比拟能够应用本义模式,如果比拟 ”ab” 和 ”bc”:[ ab < bc],后果为真,也就是返回状态为 0。[]中的逻辑与和逻辑或应用 -a 和 -o 示意。
③字符范畴。用作正则表达式的一部分,形容一个匹配的字符范畴。作为 test 用处的中括号内不能应用正则。
④在一个 array 构造的上下文中,中括号用来援用数组中每个元素的编号。
2、双中括号[[]]
①[[是 bash 程序语言的关键字。并不是一个命令,[[]] 构造比 [] 构造更加通用。在 [[和]] 之间所有的字符都不会产生文件名扩展或者单词宰割,然而会产生参数扩大和命令替换。
②反对字符串的模式匹配,应用 =~ 操作符时甚至反对 shell 的正则表达式。字符串比拟时能够把左边的作为一个模式,而不仅仅是一个字符串,比方[[hello == hell?]],后果为真。[[]] 中匹配字符串或通配符,不须要引号。
③应用 [[…]] 条件判断构造,而不是 […],可能避免脚本中的许多逻辑谬误。比方,&&、||、< 和 > 操作符可能失常存在于[[]] 条件判断构造中,然而如果呈现在 [] 构造中的话,会报错。比方能够间接应用 if [[ $a != 1 && $a != 2]], 如果不实用双括号, 则为 if [$a -ne 1] && [$a != 2]或者 if [$a -ne 1 -a $a != 2]。
④bash 把双中括号中的表达式看作一个独自的元素,并返回一个退出状态码。
例子:
if ($i<5)
if [$i -lt 5]
if [$a -ne 1 -a $a != 2]
if [$a -ne 1] && [$a != 2]
if [[$a != 1 && $a != 2]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {0..4};do echo $i;done
三、大括号、花括号 {}
1、惯例用法
①大括号拓展。(通配 (globbing)) 将对大括号中的文件名做扩大。在大括号中,不容许有空白,除非这个空白被援用或本义。第一种:对大括号中的以逗号宰割的文件列表进行拓展。如 touch {a,b}.txt 后果为 a.txt b.txt。第二种:对大括号中以点点(..)宰割的程序文件列表起拓展作用,如:touch {a..d}.txt 后果为 a.txt b.txt c.txt d.txt
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
②代码块,又被称为外部组,这个构造事实上创立了一个匿名函数。与小括号中的命令不同,大括号内的命令不会新开一个子 shell 运行,即脚本余下局部仍可应用括号内变量。括号内的命令间用分号隔开,最初一个也必须有分号。{}的第一个命令和左括号之间必须要有一个空格。必备技能!Shell 编程实战案例分享(PDF 版)!
2、几种非凡的替换构造
${var:-string},${var:+string},${var:=string},${var:?string}
①${var:-string}和 ${var:=string}: 若变量 var 为空,则用在命令行中用 string 来替换 ${var:-string},否则变量 var 不为空时,则用变量 var 的值来替换 ${var:-string};对于 ${var:=string}的替换规定和 ${var:-string}是一样的,所不同之处是 ${var:=string}若 var 为空时,用 string 替换 ${var:=string}的同时,把 string 赋给变量 var:${var:=string}很罕用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。
② ${var:+string}的替换规定和下面的相同,即只有当 var 不是空的时候才替换成 string,若 var 为空时则不替换或者说是替换成变量 var 的值,即空值。(因为变量 var 此时为空,所以这两种说法是等价的)
③${var:?string}替换规定为:若变量 var 不为空,则用变量 var 的值来替换 ${var:?string};若变量 var 为空,则把 string 输入到规范谬误中,并从脚本中退出。咱们可利用此个性来查看是否设置了变量的值。
补充扩大:在下面这五种替换构造中 string 不肯定是常值的,可用另外一个变量的值或是一种命令的输入。
3、四种模式匹配替换构造
模式匹配记忆办法:
-
是去掉右边(在键盘上 #在 $ 之右边)
- % 是去掉左边(在键盘上 % 在 $ 之左边)
-
和 % 中的繁多符号是最小匹配,两个雷同符号是最大匹配。
${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
第一种模式:${variable%pattern},这种模式时,shell 在 variable 中查找,看它是否一给的模式 pattern 结尾,如果是,就从命令行把 variable 中的内容去掉左边最短的匹配模式
第二种模式:${variable%%pattern},这种模式时,shell 在 variable 中查找,看它是否一给的模式 pattern 结尾,如果是,就从命令行把 variable 中的内容去掉左边最长的匹配模式
第三种模式:${variable#pattern} 这种模式时,shell 在 variable 中查找,看它是否一给的模式 pattern 开始,如果是,就从命令行把 variable 中的内容去掉右边最短的匹配模式
第四种模式:${variable##pattern} 这种模式时,shell 在 variable 中查找,看它是否一给的模式 pattern 结尾,如果是,就从命令行把 variable 中的内容去掉左边最长的匹配模式
这四种模式中都不会扭转 variable 的值,其中,只有在 pattern 中应用了 匹配符号时,% 和 %%,# 和 ## 才有区别。构造中的 pattern 反对通配符,示意零个或多个任意字符,? 示意仅与一个任意字符匹配,[…]示意匹配中括号外面的字符,[!…]示意不匹配中括号外面的字符。
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
4、字符串提取和替换
${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}
第一种模式:${var:num},这种模式时,(http://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==&mid=2247487485&idx=1&sn=5b4b45aca89a898a388100b09672f1af&chksm=e91b6ae1de6ce3f78b204c011e54d3e367703eb66de91aea4c0501d51e92f89000f4fbc8e3a1&scene=21#wechat_redirect)在 var 中提取第 num 个字符到开端的所有字符。若 num 为负数,从右边 0 处开始;若 num 为正数,从左边开始提取字串,但必须应用在冒号前面加空格或一个数字或整个 num 加上括号,如 ${var: -2}、${var:1-3}或 ${var:(-2)}。
第二种模式:${var:num1:num2},num1 是地位,num2 是长度。示意从 $var 字符串的第 $num1 个地位开始提取长度为 $num2 的子串。不能为正数。
第三种模式:${var/pattern/pattern}示意将 var 字符串的第一个匹配的 pattern 替换为另一个 pattern。
第四种模式:${var//pattern/pattern}示意将 var 字符串中的所有能匹配的 pattern 替换为另一个 pattern。
[root@centos ~]# var=/home/centos
[root@centos ~]# echo $var
/home/centos
[root@centos ~]# echo ${var:5}
/centos
[root@centos ~]# echo ${var: -6}
centos
[root@centos ~]# echo ${var:(-6)}
centos
[root@centos ~]# echo ${var:1:4}
home
[root@centos ~]# echo ${var/o/h}
/hhme/centos
[root@centos ~]# echo ${var//o/h}
/hhme/cenths
四、符号 $ 后的括号
(1)${a} 变量 a 的值, 在不引起歧义的状况下能够省略大括号。
(2)$(cmd) 命令替换,和 cmd
成果雷同,后果为 (http://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==&mid=2247485190&idx=1&sn=68f72ee8fba05e8cc2e1a61699df93b1&chksm=e91b621ade6ceb0cd55fa63ee03b107c8061cb594518be45048cf7c0a9de7172c0f3bdad821b&scene=21#wechat_redirect) 命令 cmd 的输,过某些 Shell 版本不反对 $()模式的命令替换, 如 tcsh。
(3)$((expression)) 和 exprexpression
成果雷同, 计算数学表达式 exp 的数值, 其中 exp 只有合乎 C 语言的运算规定即可, 甚至三目运算符和逻辑表达式都能够计算。
五、应用
多条命令执行
(1)单小括号,(cmd1;cmd2;cmd3) 新开一个子 shell 程序执行命令 cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最初一个命令后能够没有分号。
(2)单大括号,{cmd1;cmd2;cmd3;} 在以后 shell 程序执行命令 cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最初一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
对 {} 和()而言, 括号中的重定向符只影响该条命令,而括号外的重定向符影响到括号中的所有命令。
起源:乌托邦 2 号
原文:blog.csdn.net/taiyang1987912/article/details/39551385