一次讲清Shell中括号的作用

不管是多年的老手,还是涉世未深的雏,当打开shell脚本的时候,总会对各种各样的括号感到困惑,有大括号,有小括号,中括号,甚至还有两个括号[[..]]这样,今天我们就一次来讲清楚,这些括号到底是什么意思

小括号的作用

格式用途
( command1; command2 )子shell中执行命令
Array=(element1 element2 element3)数组初始化
result=$(COMMAND)执行括号中的命令,把结果赋值给result
>(COMMAND)
<(COMMAND)
Process substitution重定向
(( arithmetic ))数学运算

中括号的作用

格式用途
if [ CONDITION ]用于条件调测
if [[ CONDITION ]]扩展版条件测试
Array[1]=element1表示数组索引
[a-z]用于正则表达式中,表示范围

大括号的作用

格式用途
${variable}表示变量
${!variable}表示间接变量
{ command1; command2; . . . commandN; }本shell中批量执行指令
{string1,string2,string3}数据展开
{a..z}扩展版数据展开
{}占位符,用于find或者xargs中

下面解释其中的一些容易费解的点

Process substitution

>(COMMAND)和<(COMMAND)是Process substitution。本质是输入输出的重定向,你可能想起了管道pipe,但其实二者是有区别的:~~~好奇的传送门

双小括号用于算术运算

((..))用于算术运算

赋值运算:
# (( var = 78 )); echo $var
78

四则运算:
# (( var = 78*2 )); echo $var
156

单目运算:
# var=78; (( var-- )); echo $var
77

三目运算:
# var=77; (( var1=var>70?1:0 )); echo $var1
1

大括号间接变量

大括号除了表示变量,还可以表示间接变量,${!variable}是间接变量的用法。

间接变量的例子,从b变量得到值a,再把a当作变量,获取a的值:

# a=123;b=a;echo ${!b}
123

间接变量仅仅有一层,不能无限展开,从c只能到a,不能到123:

# a=123;b=a;c=b;echo ${!c}
a

大括号的数据展开

{string1,string2,string3}或者{a..z}是数据展开的格式。

来看例子吧。一次性建多个目录:

mkdir /usr/local/src/bash/{old,new,dist,bugs}

依次展开数据:

# echo a{d,c,b}e
ade ace abe

展开中间数据:

# echo {a..f}
a b c d e f

{}占位符

空的大括号对{}在find 中用作占位符,代表着符合条件的文件名:

find . -name "hello.txt" -execdir mv {} {}.bak \;

例子查找本目录下的所有hello.txt文件,并且把它重命名为hello.txt.bak

子shell执行和当前shell执行的区别

小括号 (和大括号{都可以批量执行命令,二者有什么区别呢?

小括号(是在子shell中执行命令,系统会新开一个shell, 一切操作不会影响当前shell的环境变量,比如:

root@iZ8vb4hv9rh422360tk6dbZ:~# (cd /home;pwd;)
/home
root@iZ8vb4hv9rh422360tk6dbZ:~# pwd
/root
root@iZ8vb4hv9rh422360tk6dbZ:~#

而大括号{是在当前shell中执行命令,命令会改变当前shell环境的变量:

root@iZ8vb4hv9rh422360tk6dbZ:~# { cd /home;pwd; }
/home
root@iZ8vb4hv9rh422360tk6dbZ:/home# pwd
/home
root@iZ8vb4hv9rh422360tk6dbZ:/home#

单中括号[和双中括号[[的区别

先简单说一下结论,二者作用是相同的,都是测试指令。[是旧版指令,[[是[的功能加强版。单中括号[在所有的Posix系统上都支持,而[[则不一定了,在Korn shell , Bash, Zsh, 和最新版本的Yash以及 busybox sh上支持

我们来大致说一下细节,你可能不知道,单个中括号[是个函数

# which [
/usr/bin/[

而我们查阅手册的时候,会进入关于test的说明。

# man [

TEST(1)                                                                User Commands                                                               TEST(1)

NAME
       test - check file types and compare values

这就很清楚了,单个的中括号[就是test函数,和test可以相互替换,一般和if, while等一起使用,写条件语句:

#  a=abcd; if [ $a = abcd ]; then echo "true"; fi
true

# a=abcd; if test $a = abcd ; then echo "true"; fi
true

但[[并不是一个函数,而是真正的shell语法。

[[提供更多的功能,比如说支持正则表达式比较,而单括号[并不能,以下指令换成单括号[执行会失败的:

# a=abcd; if [[ $a == abc* ]]; then echo "true"; fi
true

其他的还有很多,可自行查阅,比如对于逻辑表达式的支持,对于AND运算符,[使用”-a”,而[[使用”&&”,更贴近习惯

# a=abcd; if [ 1 = 1 -a 2 = 2 ]; then echo "true"; fi
true

# a=abcd; if [[ 1 = 1 && 2 = 2 ]]; then echo "true"; fi
true

Ref



发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About Me

一位程序员,会弹吉他,喜欢读诗。
有一颗感恩的心,一位美丽的妻子,两个可爱的女儿
mail: geraldlee0825@gmail.com
github: https://github.com/lisuxiaoqi
medium: https://medium.com/@geraldlee0825