Shell(Bash)小括号和大括号用法及区别

在介绍小括号和大括号的用法及区别之前,我们先解释两个概念:父 Shell 和子 Shell。

在 Bash 中,是可以调用新的 Bash 的,比如:

[root@localhost ~]# bash
[root@localhost ~]#

这时,可以通过 pstree 命令査看一下进程数,命令如下:

[root@localhost ~]# pstree
init──┬──abrt-dump-oops
…省略部分输出
├─sshd──┬──sshd───bash───bash───pstree
…省略部分输出

可以看到我们的命令都是通过 ssh 远程服务链接的,在 ssh 中生成了第一个 Bash,就是父 Shell。因为我们刚刚执行了 Bash 命令,所以在第一个 Bash 中生成了第二个 Bash,这个 Bash 就是子 Shell,我们是在子 Shell 中运行命令 pstree 的。

关于父 Shell 和子 Shell,大家可以想象成在 Windows 中我们开启了一个"cmd"字符操作终端,那么 Windows 本身就是父 Shell,而"cmd"终端则是子 Shell;也可以理解为在一个操作界面中又开启了一个操作界面。

知道了父 Shell 和子 Shell,我们接着解释小括号和大括号的区别。如果用于一串命令的执行,那么小括号和大括号主要区别在于:
  • () 执行一串命令时,需要重新开启一个子 Shell 来执行。
  • {} 执行一串命令时,在当前 Shell 中执行。
  • () 和 {} 都是把一串命令放田括号里面,并且命令之间用";"隔开。
  • () 最后一条命令可以不用分号。
  • {} 最后一条命令要用分号。
  • {} 的第一条命令和左括号之间必须有一个空格。
  • () 里的各命令不必和括号有空格。
  • () 和 {} 中括号里面的某条命令的重定向只影响该命令,但括号外的重定向则会影响到括号里的所有命令。

下面举几个例子。

[root@localhost ~]# name=sc #在父 Shell 中定义 name 的值是 sc
[root@localhost ~]# (name=liming;echo $name)
liming
#如果用()括起来一串命令,那么这些命令都可以执行
#给name变量重新赋值,但是这个值只在子Shell中
[root@localhost ~]# echo $name
sc
#父Shell中name的值还是sc,而不是liming
[root@localhost ~]#{ name=liming;echo $name;} liming
#但是用大括号来进行一串命令的执行时,name变量的修改是直接在父Shell中进行的
#注意大括号的格式
[root@localhost ~]# echo $name
liming
#name变量的值已经被修改了

其实在执行一串命令时,如果使用的是小括号,则这串命令所做的修改只在子 Shell 中生效,一旦命令执行结束,回到父 Shell 中,这个修改就会丟失;而如果使用的是大括号,则此串命令直接在父 Shell 中执行,命令执行结束后,修改依然会生效。