在 shell 中括号的功能可是五花八门,为我们编写功能强大的脚本提供了有力的支持。包括圆括号 () 方括号 [] 和花括号 {},下边分别介绍:
一. 圆括号
1. 单层圆括号中输入命令,可以把命令的结果赋值给变量:
[root@server ~]# echo "当前进程数为$(ps -ef | wc -l)"
当前进程数为87
2. 单层圆括号也可以定义数组,请看shell 编程教程(4)给力的数组_yspg_217的博客-CSDN博客
3. 双层圆括号的使用主要在算术领域
请看shell 编程教程(3)数学运算_yspg_217的博客-CSDN博客
也可以用在整数条件判断的功能中,((a>0 && a<2))、((0<=a<=2))、((a!=0))都是符合语法的。
二. 方括号
方括号在 shell 编程中起到了测试的功能,等同于 shell 自带的命令 test,可以对字符串、数字或文件进行条件判断。
1. 单层方括号的使用格式为:
test condition 或 [ condition ]
其中condition分为三种情况:
-eq | 等于 |
-ne | 不等于 |
-gt | 大于 |
-ge | 大于等于 |
-lt | 小于 |
-le | 小于等于 |
[root@server ~]# [ 1 -eq 2 ] && echo Y || echo N
N
[root@server ~]# [ 1 -ne 2 ] && echo Y || echo N
Y
[root@server ~]# [ 1 -gt 2 ] && echo Y || echo N
N
[root@server ~]# [ 1 -ge 2 ] && echo Y || echo N
N
[root@server ~]# [ 1 -lt 2 ] && echo Y || echo N
Y
[root@server ~]# [ 1 -le 2 ] && echo Y || echo N
Y
str1==str2 | str1 是否等于 str2 |
str1!=str2 | str1 是否不等于 str2 |
-z str | str 长度是否为 0 |
-n str | str 长度是否不为 0 |
[root@server ~]# [ $name == "David" ] && echo Y || echo N
Y
[root@server ~]# [ $name != "David" ] && echo Y || echo N
N
[root@server ~]# [ -z $name ] && echo Y || echo N
N
[root@server ~]# [ -n $name ] && echo Y || echo N
Y
-e filename | 文件是否存在 |
-s filename | 文件是否为非空 |
-r filename | 文件是否存在且可读 |
-w filename | 文件是否存在且可写 |
-x filename | 文件是否存在且可执行 |
-b filename | 文件是否是块设备文件 |
-c filename | 文件是否是字符设备文件 |
-d filename | 文件是否是目录 |
-f filename | 文件是否是普通文件 |
-L filename | 文件是否是软链接 |
-S filename | 文件是否是套接字 |
-p filename | 文件是否是管道 |
-O filename | 当前用户是否是文件属主 |
-G filename | 当前用户组是否是文件属组 |
file1 -ot file2 | file1 是否比 file2 修改时间更旧 |
file1 -nt file2 | file1 是否比 file2 修改时间更新 |
file1 -ef file2 | inode号是否一致,判断硬链接 |
[root@server dir]# [ -f file5 ] && echo Y || echo N
Y
[root@server dir]# [ -r file5 ] && echo Y || echo N
Y
[root@server dir]# [ -w file5 ] && echo Y || echo N
Y
[root@server dir]# [ -x file5 ] && echo Y || echo N
N
[root@server dir]# [ -z file5 ] && echo Y || echo N
N
[root@server dir]# [ -s file5 ] && echo Y || echo N
N
单层方括号在需要使用复合条件时,一种格式是(其中逻辑运算符可选的是 && 和 ||):
[ condition1 ] 逻辑运算符 [ condition2 ]
另一种格式是在括号内部(这里的逻辑运算符可选的是 -a 和 -o):
[ condition1 逻辑运算符 condition2 ]
condition 前可以添加!代表非condition。
[root@server dir]# [ -e file5 ] || [ 1 -eq 2 ] && echo Y || echo N
Y
[root@server dir]# [ -e file5 ] && [ 1 -eq 2 ] && echo Y || echo N
N
[root@server dir]# [ -e file5 -o 1 -eq 2 ] && echo Y || echo N
Y
[root@server dir]# [ -e file5 -a 1 -eq 2 ] && echo Y || echo N
N
[root@server dir]# [ ! -e file5 ] && echo Y || echo N
N
2. 双层方括号
在语法上对单层方括号进行了扩展,最大的变化是支持括号内的逻辑运算符(&& ||)。
①数字的测试没有变化,更推荐使用上边的双圆括号的格式
②字符串测试增加了比较运算符小于号和大于号(<、>),作用是按字母顺序排序。另外 == 的作用变成了模式匹配。
③字符串测试增加了正则表达式匹配,格式为[[ str =~ regex ]],正则表达式的用法请看神奇的正则表达式_yspg_217的博客-CSDN博客
[root@server ~]# [[ $name == "David" ]] && echo Y || echo N
Y
[root@server ~]# [[ $name != "David" ]] && echo Y || echo N
N
[root@server ~]# [[ $name > "Davi" ]] && echo Y || echo N
Y
[root@server ~]# [[ $name < "Davidd" ]] && echo Y || echo N
Y
[root@server ~]# [[ $name < "Eavid" ]] && echo Y || echo N
Y
[root@server ~]# [[ $name < "Cavid" ]] && echo Y || echo N
N
[root@server ~]# [[ $name == "David" && 1+1==2 ]] && echo Y || echo N
Y
[root@server ~]# [[ $name == "David" || 1+1!=2 ]] && echo Y || echo N
Y
[root@server ~]# [[ $name =~ [a-z]+ ]] && echo Y || echo N
Y
三. 花括号
1. 与逗号配合可以产生可选字符的效果,什么意思呢?看例子:
[root@server ~]# touch {a,b,c}
[root@server ~]# ll {a,b,c}
-rw-r--r-- 1 root root 0 2月 28 23:06 a
-rw-r--r-- 1 root root 0 2月 28 23:06 b
-rw-r--r-- 1 root root 0 2月 28 23:06 c
[root@server ~]# touch t{a,i,o}p
[root@server ~]# ll
-rw-r--r-- 1 root root 0 2月 28 23:11 tap
-rw-r--r-- 1 root root 0 2月 28 23:11 tip
-rw-r--r-- 1 root root 0 2月 28 23:11 top
2. 与两个点号配合,表示一个字符范围,看例子:
[root@server ~]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@server ~]# echo {a..z..2}
a c e g i k m o q s u w y
[root@server ~]# echo {1..9}
1 2 3 4 5 6 7 8 9
3. 变量替换:
${var} | 引用 var 变量的值,在 shell 编程教程(1)中就讲到了这个使用方式 |
${var-key} | 如果 var 未定义,返回 key,否则返回 var 的值 |
${var:-key} | 如果 var 为空或未定义,返回 key,否则返回 var 的值 |
${var:=key} | 如果 var 为空或未定义,将 key 赋值给 var 并返回,否则返回 var 的值 |
${var:?key} | 如果 var 为空或未定义,显示包含 key 的错误信息,否则返回 var 的值 |
${var:+key} | 如果 var 为空或未定义,返回空,否则返回 key |
${var:offset} | 从 offset 位置开始,到 var 的结尾,offset 的值从0开始 |
${var:offset:len} | 从 offset 位置开始,截取 len 长度 |
${var#key} | 使用 key 进行从左往右的模式匹配,匹配到的部分删除,最短匹配 |
${var##key} | 使用 key 进行从左往右的模式匹配,匹配到的部分删除,最长匹配 |
${var%key} | 使用 key 进行从右往左的模式匹配,匹配到的部分删除,最短匹配 |
${var%%key} | 使用 key 进行从右往左的模式匹配,匹配到的部分删除,最长匹配 |
${!var} | var 的值为名称的变量的值 |
${!prefix*} | 查找以 prefix 开头的变量名 |
${!prefix@} | 查找以 prefix 开头的变量名,@在引号中被扩展为独立单词 |
${array[*]} | 列出 array 的所有元素,*在引号中被扩展为一个整体 |
${array[@]} | 列出 array 的所有元素,@在引号中被扩展为独立单词 |
${!array[*]} | 列出 array 中的所有下标,*在引号中被扩展为一个整体 |
${!array[@]} | 列出 array 中的所有下标,@在引号中被扩展为独立单词 |
${#var} | var 的长度,var 可以是数组 |
${var/oldstr/newstr} | 将 var 中的 oldstr 替换为 newstr,替换第一个 |
${var//oldstr/newstr} | 将 var 中的 oldstr 替换为 newstr,替换所有 oldstr |
${var^^pattern} | 将 var 中的 pattern 的小写替换为大写,替换所有 |
${var,,pattern} | 将 var 中的 pattern 的大写替换为小写,替换所有 |
操作实例(数组相关的功能请看shell 编程教程(4)数组):
#!/bin/bash
name="David"
David="somebody"
echo ${name}
echo ${David}
echo ${!name}
echo ${name-"未定义"}
echo ${name:-"未定义"}
echo ${age:-"未定义"}
echo ${name:="Kevin"}
echo ${age:=18}
echo ${name:?"name未定义"}
echo ${age:?"age未定义"}
echo ${name:+"name已定义"}
echo ${age:+"age已定义"}
alphabet="abcdefghijklmnopqrstuvwxyz"
echo ${alphabet:12}
echo ${alphabet:2:10}
sentence="Experience is the Mother of WisdoM."
echo ${sentence#*s}
echo ${sentence##*s}
echo ${sentence%s*}
echo ${sentence%%s*}
echo ${#sentence}
echo ${sentence/e/o}
echo ${sentence//e/o}
echo ${sentence^^[eo]}
echo ${sentence,,[MW]}
echo ${!a*}
echo ${!a@}
David
somebody
somebody
David
David
未定义
David
18
David
18
name已定义
age已定义
mnopqrstuvwxyz
cdefghijkl
the Mother of WisdoM.
doM.
Experience is the Mother of Wi
Experience i
35
Exporience is the Mother of WisdoM.
Exporionco is tho Mothor of WisdoM.
ExpEriEncE is thE MOthEr Of WisdOM.
Experience is the mother of wisdom.
age alphabet
age alphabet