提示:本篇文章接上一篇文章,主要說說
()
小括號和{}
大括號的區別與使用。
8、()
小括號
()
:用於一串命令執行時,()
中的命令會在子Shell中執行。(和下面大括號一起說明)
9、{}
大括號
{}
:用於一串命令執行時,{}
中的命令會在當前Shell中執行。也可以用於變數變形與替換。
(1)父Shell和子Shell
在介紹小括號和大括號的區別之前,我們先要解釋一個概念,那就是父Shell和子Shell。
使用者登入到Linux系統後,系統將啟動一個使用者Shell。在這個Shell中,可以使用Shell命令宣告變數,也可以建立並執行Shell指令碼程式。執行Shell指令碼程式時,系統將建立一個子Shell。此時,系統中將有兩個Shell,一個是登入時系統啟動的Shell,另一個是系統為執行指令碼程式建立的Shell。當一個指令碼程式執行完畢,它的指令碼Shell將終止,可以返回到執行該指令碼之前的Shell。從這種意義上來 說,使用者可以有許多Shell,每個Shell都是由某個Shell(稱為父Shell)派生的。
在Linux系統中的預設Shell是bash
,在bash
中是可以呼叫新的bash
的。在開啟遠端終端時候所啟動的預設的互動Shell就是父Shell,只需要直接執行bash
命令,就會建立一個新的Shell,這個Shell就是子Shell。
執行下面命令:
[root@localhost ~]# bash
我們就開啟一個子Shell。
(2)區分父Shell子Shell
要區分是父Shell還是子Shell,需要使用前面所學的ps
命令,檢視程式命令來進行判斷。
- 執行
ps -f
檢視系統程式。
- 執行
bash
命令,開啟一個新的Shell,並再次檢視系統程式。
可以看到上圖中,第二個程式的父id
是第一個程式,所以第二個程式的bash
是子Shell。 - 退出子Shell,並再次檢視系統程式。
可以看到子Shell程式結束,消失了。
(3)檢視父子Shell的關係
我們可以通過pstree
命令(檢視程式樹),來檢視父子Shell的關係。
在Red Hat 6 中,所有的程式都是init
程式的子程式。如下圖:
我們可以看到在init
程式下,開啟了一個sshd
的程式,這個程式就是遠端登陸程式。我們執行過一次遠端登陸sshd
,和開啟bash
功能,在此bash
下執行過一次pstree
命令。
在當前Shell中,再執行一邊bash
命令,再次執行pstree
命令(檢視程式樹)。
如下圖:
我們可以從上圖中看到,我在第一個bash
下,又開啟了一個新的bash
,在新bash
中執行了pstree
命令。
所以說第一個bash
是父(也就是父Shell),第二個bash
是子(也就是子Shell)。
(4)父子Shell的關係擴充。
父Shell可以建立子Shell,在子Shell中還可以建立自己的子Shell。
它們的關係如下圖所示:
下面來演示下這個關係圖的Shell建立,和它們之前的關係層次。
下圖中又建立了二個子Shell,總共三個子Shell。依次是子Shell, 孫Shell, 曾孫Shell。
下圖使用ps -f
命令,通過PPID列出誰是誰的父程式。
注意:生成子Shell的成本不低,而且速度還慢,建立巢狀的子Shell去處理命令程式效能更為嚴重。
通過輸入exit
命令能有條不絮的退出子Shell,例如上面的三個子Shell, 首先從曾孫Shell退出。
如下圖所示:
注意:當沒有了子Shell時,再輸入
exit
命令,將退出控制檯終端。
(5)小括號和大括號的區別
知道了父Shell和子Shell的關係,我們接著解釋小括號和大括號的區別。
小括號和大括號的主要區別在於,在Shell程式執行的時候,小括號或者大括號中的內容是在父Shell執行還是在子Shell中執行。
下面我們總結一下小括號和大括號的主要區別:
()
中執行一串命令時,需要重新開一個子Shell進行執行。
在當前Shell中name=ss
,當執行到()
中命令的時候,會自動開啟一個子Shell,在子Shell中name
的變數賦予了mm
,當()
中命令執行完,子Shell程式就結束了,程式消失。裡邊的變數都不會儲存,並自動返回到父Shell中,也就是迴歸到當前Shell,name
的值還是原來Shell中賦予的ss
值。
示例如下:#在父Shell中定義變數name的值是ss [root@localhost ~]# name=ss #如果用()括起來一串命令,這些命令都可以執行。 #給name變數重新賦值,但是這個值只在子Shell中生效 [root@localhost ~]#(name=mm;echo $name) mm #父Shell中name的值還是ss,而不是mm [root@localhost ~]# echo $name ss
{ }
中執行一串命令時,是在當前Shell執行。
就相當於直接在當前Shell執行#用大括號來進行串命令的執行時 #name變數的修改是直接在父Shell當中的 #注意大括號的格式 [root@localhost ~]# { name=mm;echo $name; } mm #所以name變數的值已經被修改了 [root@localhost ~]# echo $name mm
{}
中的語句,那麼不寫{}
的結果是一樣的。()
和{}
都是把一串的命令放在括號裡面,並且命令之間用;
號隔開。()
最後一個命令可以不用分號結尾。[root@localhost ~]# ( name=lm; echo $name )
{}
中最後一個命令要用分號結尾。[root@localhost ~]# { 空格 name=lm; echo $name; }
{}
中的第一個命令和左括號之間必須要有一個空格。[root@localhost ~]# { 空格 name=lm; echo $name; }
()
裡的各命令不必和括號有空格。()
和{}
中,括號裡面的某個命令的重定向隻影響該命令,但括號外的重定向則影響到括號裡的所有命令。
說明:小括號和大括號不太好理解,用的也不是太多,能看懂即可,工作中用不用在你自己。
10、[]
中括號
[]
:用於變數的測試。(之後詳解講解)