已复制
全屏展示
复制代码

BASH常见特殊符号


· 3 min read

一. ()

  • 用作数组,数组的元素如果有模糊的正则匹配,那么首先会看是否在指定路径能不能找到,如果找不到则原样输出。
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

文章推荐