Shell組命令

2020-07-16 10:04:46
所謂組命令,就是將多個命令劃分為一組,或者看成一個整體。

Shell 組命令的寫法有兩種:

{ command1; command2; command3; . . .  }
(command1; command2; command3;. . . )

兩種寫法的區別在於:由花括號{}包圍起來的組命名在當前 Shell 進程中執行,而由小括號()包圍起來的組命令會建立一個子 Shell,所有命令都在子 Shell 中執行。

對於第一種寫法,花括號和命令之間必須有一個空格,並且最後一個命令必須用一個分號或者一個換行符結束。

子 Shell 就是一個子進程,是通過當前 Shell 進程建立的一個新進程。但是子 Shell 和一般的子進程(比如bash ./test.sh建立的子進程)還是有差別的,我們將在《子Shell和子進程》一節中深入講解,讀者暫時把子 Shell 和子進程等價起來就行。

組命令可以將多條命令的輸出結果合併在一起,在使用重定向和管道時會特別方便。

例如,下面的程式碼將多個命令的輸出重定向到 out.txt:
ls -l > out.txt  #>表示覆蓋
echo "http://c.biancheng.net/shell/" >> out.txt  #>>表示追加
cat readme.txt >> out.txt
本段程式碼共使用了三次重定向。

借助組命令,我們可以將以上三條命令合併在一起,簡化成一次重定向:

{ ls -l; echo "http://c.biancheng.net/shell/"; cat readme.txt; } > out.txt

或者寫作:

(ls -l; echo "http://c.biancheng.net/shell/"; cat readme.txt) > out.txt

使用組命令技術,我們節省了一些打字時間。

類似的道理,我們也可以將組命令和管道結合起來:

{ ls -l; echo "http://c.biancheng.net/shell/"; cat readme.txt; } | lpr

這裡我們把三個命令的輸出結果合併在一起,並把它們用管道輸送給命令 lpr 的輸入,以便產生一個列印報告。

兩種組命令形式的對比

雖然兩種 Shell 組命令形式看起來相似,它們都能用在重定向中合併輸出結果,但兩者之間有一個很重要的不同:由{}包圍的組命令在當前 Shell 進程中執行,由()包圍的組命令會建立一個子Shell,所有命令都會在這個子 Shell 中執行。

在子 Shell 中執行意味著,執行環境被複製給了一個新的 shell 進程,當這個子 Shell 退出時,新的進程也會被銷毀,環境副本也會消失,所以在子 Shell 環境中的任何更改都會消失(包括給變數賦值)。因此,在大多數情況下,除非指令碼要求一個子 Shell,否則使用{}比使用()更受歡迎,並且{}的進行速度更快,佔用的記憶體更少。