參考:http://www.zsythink.net/archives/1166
在shell中,有兩種組合命令的方法,在介紹這兩種方法之前,我們先來看一個小示例。
目前有兩個目錄,這兩個目錄分別為/test1和/test2,目錄中分別存在如下文件。
[root@node1 ~]# ls /test1 t1 t2 t3 [root@node1 ~]# ls /test2 t4 [root@node1 ~]#
此刻,如果我們想要統計這兩個目錄中一共有多少個文件,該怎樣編寫shell呢,編寫如下的shell命令,能夠達到目的嗎?
[root@node1 ~]# ls /test1;ls /test2 | wc -l
上述命令是無法統計出兩個目錄中的文件數量的,因為執行結果如下。
[root@node1 ~]# ls /test1;ls /test2 | wc -l t1 t2 t3 1 [root@node1 ~]#
從上述執行結果可以看出,前兩條命令並沒有一起執行,而是第一條命令執行完畢后,再把后面的命令當做一個整體執行了,即執行了第一條命令顯示了文件夾/test1下三個文件名 然后把ls /test2 | wc -l作為一條語句執行了打印了文件夾下面多少個文件數即1
那么如果我們想要讓前兩條命令當做一個整體執行,該怎樣做呢?
[root@node1 ~]# (ls /test1;ls test2)| wc -l 4 [root@node1 ~]# { ls /test1;ls test2; }| wc -l 4 [root@node1 ~]#
上圖中,我們分別使用小括號"( )" 與 大括號"{ }"將前兩個命令組合在了一起。兩種方法都能達到我們的目的,但是,這兩種方法是有所不同的,先說說第一種,當使用"小括號"將兩條命令括起以后,這兩條命令相當於在當前shell的子shell中執行,也就是說,這兩條命令並不是在當前進程中運行的,而是在當前進程的子進程中運行的,而使用"大括號"時則不同,被大括號括起的命令是在當前進程中執行的。那么,我們怎樣證明上述理論呢,我們可以做一個小實驗,如下圖。
[root@node1 ~]# (cd;exit) [root@node1 ~]# { cd;exit; } 登出 Connection closing...Socket close. Connection closed by foreign host. Disconnected from remote host(local-iptables-test-001146) at 13:43:46. Type `help' to learn how to use Xshell prompt. [C:\~]$
當我們使用小括號將命令聚合以后,因為是在子進程中執行,所以即使exit命令生效,也是退出子進程,而不是退出當前shell進程,但是如果使用大括號將命令組合,則表示在當前shell進程中運行命令,所以,當exit命令生效時,則會退出當前shell進程。
好了,這就是使用"大括號"與使用"小括號"的不同之處,其實,在使用大括號時,還需要注意一些額外的注意點,細心如你一定已經發現了,上述所有使用"大括號"的示例中,大括號內的所有命令都用空格隔開了,而且大括號內的每個命令都必須以分號";"結尾,即使是大括號內的最后一個命令,也需要以分號結尾,而且需要用空格與大括號隔開,這就是使用這種方法的注意點,其實,這種用大括號聚合命令的方法是使用了函數中"代碼塊"的語法,在函數中,一個函數的代碼塊就會用大括號括起,表示是一個函數的整體,此處我們也可以這樣理解,我們將多個命令用大括號括起,表示他們是一個代碼塊,是一個整體,我們可以把這種沒有函數名只有函數體的代碼塊理解為匿名函數,當然,如果你還不了解shell的函數,沒有關系,只需要記住這種用法即可。