BASH常见特殊符号
一. ()
- 用作数组,数组的元素如果有模糊的正则匹配,那么首先会看是否在指定路径能不能找到,如果找不到则原样输出。
array=(/etc/mysql/conf.d/* "b b" c* d)
for i in ${!array[@]};do
echo ${array[i]}
done
# 结果
/etc/mysql/conf.d/mysql.cnf
/etc/mysql/conf.d/mysqldump.cnf
b b
c*
d
- 执行命令:执行多条命令的组合
[yzy@yzym ~]$ (cd /var/; pwd)
/var
二. $()
$()用于执行命令,declare -p var
可以看到变量的类型和值。$()
与 `` 都可以执行命令,但是 $() 可以多层嵌套执行,``无法嵌套执行。
var=$(pwd; cd /etc/mysql/conf.d/; ls)
declare -p var
# 结果
declare -- var="/home/cs/scripts
mysql.cnf
mysqldump.cnf"
三. $(())
$(())
用作计算数学表达式,在括号里面的运算符不需要转移,控制运算的先后顺序也可以用()
来控制,非常方便。
var=$(( 9*(9+1) ))
echo $var
90
var=$(( 9+1*9 ))
echo $var
18
- 另一个算术运算命令
let
,可以同时给多个变量赋值或计算。
let a=9+8/8
echo $a
10
let a=9+8/8 b=8*7+2*2
echo $a $b
10 60
i=0
while [ $i -lt 5 ]; do
echo $i
let i++
done
0
1
2
3
4
- 另一中求算术运算的方法
i=$[6+3*3]
echo $i
15
四. < <()
执行命令以后将结果作为标准输入,第一个<
表示重定向,第二个<()
表示Process substitution
,这里<(cat /etc/profile)
与/etc/profile
等效,其实是把文件作为输入的地方换成了任意可以执行的命令了。
# 统计文件行数:这种方式时,在同一个shell里面执行
while read line; do ((cnt++)); done < <(cat /etc/profile)
echo $cnt
27
# 统计文件行数:管道是在不同的 shell 执行,所以为cnt的值为0
cat /etc/profile | while read line; do ((cnt++)); done;
echo $cnt
0
五. > >()
同上,在同一个shell里面将前面命令的输出作为>()
里面命令的输入了,第一个>
表示重定向
cat /etc/profile > >( awk '{cnt+=1}END{print cnt}' )
27
# ">> >(" 同 "> >(" 因为都是重定向
cat /etc/profile >> >( awk '{cnt+=1}END{print cnt}' )
27
六. <<<
<<<
将变量作为输入
# 输出为空是因为在子 shell 里面了
var="hello world"
echo "$var" | read first second
echo $second $first
# 解决办法是使用 <<< 代替管道
var="hello world"
read first second <<< "$var"
echo $second $first
七. []
[]
用作条件判断,可以判断数字、字符串、文件、逻辑判断等。它和test
命令等价。
[ $# -eq 0 ] && echo good
八. [[]]
[[]]
说是[]
的增强版,它能够将多个条件判断组合起来,根据不同的条件,同样它的内部也需要空格。它的用法和[]
一致,好处是不需要再额外转义某些特殊字符了。
[[ 9 > 8 ]] && echo 1
1
[ 9 \> 8 ] && echo 2
2
[[ -e /etc ]] && echo 3
3
[[ "able" == "able" ]] && echo 4
4
[[ "able" == "able" && "cc" == "cc" ]] && echo 5
5
[[ "able" == "able_" || "cc" == "cc" ]] && echo 6
6
九. {}
{}
是一个匿名函数,这个匿名函数里面可以放多条执行语句,注意:
- 匿名函数必须有一个执行语句,哪怕是
:
也行。 - 括号内部边缘必须要有空格。
- 每一条语句都必须要
;
结尾。 - 如果语句多的话,最好写成有名字的函数。
{ :; }
[ -e /etc ] && { echo "/etc exists"; echo "ready to edit"; }
/etc exists
ready to edit
func1(){
...
...
}
十. ${}
精确的界定变量名称的范围,避免变量名称和其他字符串组合。
# 字符串
var="able"
echo ${var}
# 数组
arr1=(a b c d)
for i in ${arr1[@]}; do
echo $i
done
# 字典
declare -A dict1
dict1=(["name"]="yzy" ["age"]=18 ["home"]="beijing")
for i in ${!dict1[@]}; do
echo $i is ${dict1[$i]}
done