shell 编程教程(5)括号的妙用()[]{}

在 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==str2str1 是否等于 str2
str1!=str2str1 是否不等于 str2
-z strstr 长度是否为 0
-n strstr 长度是否不为 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 file2file1 是否比 file2 修改时间更旧
file1 -nt file2file1 是否比 file2 修改时间更新
file1 -ef file2inode号是否一致,判断硬链接
[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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值