Bash中有各种括号,包括单小括号,双小括号,单中括号,双中括号,单大括号。而且它们之间很容易混淆,所以很有必要总结一下它们的用法。
1. ()的用法
单个小括号用来创建一个子shell。例如:
$ pwd
/home/xfeng
$ (cd /tmp; pwd)
/tmp
你可以看到,子shell允许你在不影响当前shell的环境下去执行操作。
此外,()还有命令替换的功能,result=$(command)与result=`command`有同样的效果。
fengxi@ubuntu:~/bash$ var=$(pwd)
fengxi@ubuntu:~/bash$ echo $var
/home/fengxi/bash
2. (())的用法
两个小括号用来对整数进行算术运算。比如
fengxi@ubuntu:~/bash$ var=$(20+5)
20+5: command not found
是会报错的,报错内容为:20+5: command not found。但是用双小括号就没有问题
fengxi@ubuntu:~/bash$ var=$((20+5))
fengxi@ubuntu:~/bash$ echo $var
25
此外,(())还具有C语言类型变量增减的功能。如:
fengxi@ubuntu:~/bash$ var=2
fengxi@ubuntu:~/bash$ (( var++ ))
fengxi@ubuntu:~/bash$ echo $var
3
fengxi@ubuntu:~/bash$ (( var-- ))
fengxi@ubuntu:~/bash$ echo $var
2
3. []的用法
单个中括号[]通常调用一个名为[的程序,你可以用man查询一下[,它的返回结果和man test的结果是一样的。[和test都是bash的builtin函数。
fengxi@ubuntu:~/bash$ var=123
fengxi@ubuntu:~/bash$ if [ $var == 123 ]; then echo yes; else echo no; fi
yes
在[]中等于==和=的效果是一样的
fengxi@ubuntu:~/bash$ if [ $var = 123 ]; then echo yes; else echo no; fi
yes
4. [[]]的用法
[[比起[来说,它是一个关键字,并不是一个程序,它带来了额外的功能。例如,你可以使用&&或者||而不是-a或者-o,而且还有正则表达式匹配操作符=~。&&和||仅仅能够用在[[中,在[中则会报错。
fengxi@ubuntu:~/bash$ if [[ var != 4 && var != 3 ]]; then echo $var; fi
5
fengxi@ubuntu:~/bash$ if [ var != 4 && var != 3 ]; then echo $var; fi
bash: [: missing `]'
重点:[和[[对数字的判断仅仅可用于等于还是不等于,如果是涉及到数学运算则需要借助于expr操作来实现,比如我要想得到100以内既能被3整除又能被4整除的所有数,则程序应该这样写:
for i in `seq 100`
do
if [ `expr $i % 12` = 0 ]
then
echo $i
fi
done
for((i=0;i<100;i++))
do
if ((i%12==0))
then
echo $i
fi
done
5. {}的用法
{}主要应用在参数展开(parameter expansion)上。
${varname:-word} 如果varname存在且非null,则返回其值;否则,返回word
${varname:=word} 如果varname存在且不是null,则返回它的值;否则,设置它为word,并返回其值
${varname:?message} 如果varname存在且非null,则返回它的值;否则,显示varname:message,并退回当前的命令或脚本。省略message会出现默认信息parameter null or not set。用途:主要是为了捕捉由于变量未定义所导致的错误。
${varname:+word} 如果varname存在且非null,则返回word,否则,返回null。
此外,{}也应用在模式匹配运算符上,假设变量path的值为/home/fengxi/long.file.name如下所示:
${variable#pattern}如果模式匹配与变量值的开头处,则删除匹配的最短部分,并返回剩下的部分。
例:${path#/*/} 结果为:fengxi/long.file.name
${variable##pattern} 如果模式匹配与变量值的开头处,则删除匹配的最长部分,并返回剩下部分。
例:${path##/*/} 结果为:long.file.name
${variable%pattern} 如果匹配模式匹配与变量的结尾处,则删除匹配的最短部分,并返回剩下部分。
例:${path%.*} 结果为:/home/fengxi/long.file
${variable%%pattern} 如果匹配模式匹配与变量的结尾处,则删除匹配的最长部分,并返回剩下的部分。
例:${path%%.*} 结果为:/home/fengxi/long
巧记方法:因为#在键盘上$的左侧,也就是前面,%在键盘上$的右侧,也就是后面。所以#匹配的头部,%匹配的是尾部。