來自:yesky
【導讀】《Linux 命令、編輯器和外殼編程實踐指南》一書的作者 Mark G. Sobell 在接受 LinuxPlanet 欄目采訪時談了他本人對 Linux 命令行命運的看法。
LinuxPlanet(以下簡稱 LP):命令行死亡了嗎?
答:不,根本就沒有死亡。對於某些人和執行某些任務來說,使用圖形界面更容易和更簡潔。這實際上依賴於你要做什麼和你是誰。圖形用戶界面和命令行之間的區別就像自動變檔與變速桿一樣。我使用變速桿是因為它能夠讓我更好地控制汽車,讓我更多地感覺到汽車在做什麼以及汽車是如何做到的。
當然,這個討論假設你是以系統管理員的級別操作文件的。有些應用程序有用戶圖形界面,有些應用程序也許沒有這種界面,或者只有非常原始的命令行界面。設法從命令行運行這些應用程序是沒有意義的。
對命令行有好處的一件事情是它能夠讓你訪問數百個工具軟件。在命令行上面,你可以使用一個管道把工具軟件結合在一起執行一項單個工具軟件無法完成的工作。下面是從我的“Linux 命令、編輯器和外殼編程實踐指南”一書中摘錄的部分內容,談了有關這些管道及其連接的過程:
“一個過程是 Linux 執行一個命令。過程之間的通信是 UNIX/Linux 的驗證證明之一。一個通道(書寫為垂直的直線“|”,在命令行中或者鍵盤上是一個垂直的實線)提供了這種通信最簡單的方式。簡單地說,一個通道接受一個工具軟件的輸出,然後把那個輸出輸入到其它工具軟件。使用 UNIX/Linux 的詞匯,這個通道接受了一個過程的標准輸出,並把這個標准的輸出作為另一個過程的標准輸入。一個過程在屏幕上顯示的大多數內容將發送給標准的輸出。如果你沒有重新定向這個輸出,這個輸出就在屏幕上顯示出來。使用一個通道,你可以重新定向這個輸出,這樣它就變成了另一個工具軟件的標准的輸入。”
例如,你可以把列出目錄中文件的命令“ls”與計算一個目錄中的文件和字數的命令“wc -w”結合在一起使用:
$ ls | wc -w
45
在 Linux 系統管理領域,用戶圖形界面通常是建在命令行工具之外的,因此,你不能得到用戶圖形界面工具的好處。當然,除非你能使用鼠標。你在命令行下面能夠完成的工作在圖形用戶界面系統管理工具中經常無法完成。
Bourne 和 Bourne 外殼程序
LP:你能討論一下 bash(Bourne Again Shell)並且解釋一下它與原來的 Bourne 外殼程序有什麼區別嗎?
答:這個外殼程序(shell)是命令行的解釋程序,它分析你輸入的命令行並且調用你申請的程序,並且把你在命令行中輸入的參數傳遞給這個程序。這個外殼程序也是一種高級的編程語言。bash 是許多 Linux 系統默認的外殼程序。大多數 Linux 發布版軟件還包含其它的外殼程序,甚至還有更多的外殼程序可供下載。
由 GNU 計劃編寫的 bash 包含了原始版本的 Bourne 外殼程序,那是 AT&T 公司發布的 UNIX 下面的第一個外殼程序。我曾經建議讀者考慮使用 C 外殼程序作為他們的交互式外殼程序,因為它擁有原始版本的 Bourne 外殼程序所沒有的一些重要功能。目前,bash 擁有所有這些功能,而且某些 bash 還包括命令完成、歷史(這樣你可以編輯和重復以前的命令)和工作控制(允許你在前端和後端之間轉移工作)等功能。當然,你可以使用 bash 編寫外殼程序腳本(批處理文件)。
許多 Linux 系統外殼程序腳本是從“#!/bin/sh”開始的。這一行命令讓腳本在外殼程序下運行。這個外殼程序不是 Bourne 外殼程序的一部分,而是一個指向 bash 的鏈接。
由於具有長期的和成功的歷史,原始的 Bourne 外殼程序一直用來編寫許多幫助管理 Unix 系統的外殼腳本。其中有些在 Linux 中出現的腳本稱作 bash 腳本。雖然 bash 腳本包含了許多原始的 Bourne 外殼程序中所沒有的擴展功能和特性,但是,bash 保持了對原始的 Bourne 外殼程序的兼容,因此你可以在 bash 下面運行 Bourne 外殼腳本。原始的 Bourne 外殼程序在 Unix 系統中稱作 sh。在 Linux 系統中,sh 是指向 bash 的一個符號鏈接,以確保需要 Bourne 外殼程序的腳本能夠運行。當被稱作 sh 的時候,bash 盡最大的努力效仿原始的 Bourne 外殼程序。
LP:你會建議 Linux 的新手學習 bash 還是學習 TC 外殼程序?
答:如果你是一個頑固的 C 語言外殼程序員,你可以繼續使用 TC 外殼程序(tcsh)。否則,我建議你使用 bash。幾乎所有的控制 Linux 的管理外殼腳本程序都是由 bash 運行的。因此,如果你學習 bash,你將能夠很容易地理解和修改這些腳本。
awk
LP:你為什麼使用 awk?
答:這是一個很好的問題,特別是在很多人直接使用 Perl 語言的時候。這個工具軟件簡單而功能強大。在 Perl 出現之前,awk 一直是操作文件的工具之一。目前,awk 仍是有用的。GNU 版本的 awk 稱作 gawk,有一些新的功能,使其成為一個非常有用的工具。下面是我的書中討論的有關如何讓 gawk 與協作進程之間相互通信的部分內容:
協作進程:雙向 I/O
協作進程是與另一個進程並行運行的一個進程。從 3.1 版本開始,gawk 能夠啟動一個協作進程直接與後台進程交換信息。當你在客戶機/服務器環境中工作,設置一個SQL前端和後端或者在一個網絡上與一個遠程系統交換數據的時候,協作進程是很有用的。gawk 句法通過在啟動後台進程的程序名稱前面添加一個運算符號“|&”來識別一個協助進程。
一個協助進程指令必須是一個過濾器(也就是說,它讀取標准的輸入並且寫入標准的輸出),必須在完成一行輸出之後就進行刷新,而不是積累很多行很以後再進行輸出。當一個指令作為協作進程被啟動之後,它將通過一個雙向的通道與一個 gawk 程序連接,這樣,你就可以對這個協作進程進行讀寫操作。
當與 tr 工具一起使用時,這個工具在完成每一行指令之後不刷新其輸出。這個“to_upper”外殼腳本是不刷新其輸出的tr指令的外殼。這個過濾器可以作為協作進程運行。對於讀取的每一行指令,“to_upper”寫入這些行,並且把這些行翻譯成大寫字母和標准的輸出。如果你要 “to_upper”顯示調試的輸出,可刪除“set -x”前面的“#”。
$ cat to_upper
#!/bin/bash
#set -x
while read arg
do
echo "$arg" | tr '[a-z]' '[A-Z]'
done
$ echo abcdef | to_upper
ABCDEF
g6 程序啟動“to_upper”作為一個協作進程。這個 gawk 程序讀取標准的輸入或者在命令行中指定的一個文件,把這個輸入翻譯成大寫字母,並把翻譯的數據寫入一個標准的輸出。
$ cat g6
{
print $0 |& "to_upper"
"to_upper" |& getline hold
print hold
}
$ gawk -f g6 < alpha
AAAAAAAAA
BBBBBBBBB
CCCCCCCCC
DDDDDDDDD
這個g6程序在括號之內有一個混合的指令,包含三個指令。由於沒有執行方式,gawk 對於每一行輸入內容都執行一次這個混合的指令。
第一個指令“print $0”把當前的記錄發送到標准的輸出。“|&”運算符把標准的輸出從新指向名為“to_upper”的程序。“to_upper”作為一個協作進程在運行。這些程序的外邊需要一個括號。第二個指令把來自“to_upper”的標准輸出重新指向一個“getline”指令。這個指令將其標准的輸出復制到這個名為“hold”的變量。第三個指令“print hold”把“hold”變量的這個內容發送到標准的輸出。
這個工具的名稱是“tr”
LP:你能不能更多地談一下“tr”工具?
答:哦,tr,好的。首先想到的事情是這是一個微不足道的問題的答案。命名一個 Linux 工具。這個工具僅接收來自標准輸入的輸入,從來不接收作為來自命令行變量的文件的輸入。這個怪物只是有時候有用,但是,當它有用的時候,它是非常有用的。下面是摘錄一些有關“tr”的內容:
tr 工具讀取標准輸入中每一個輸入的字符,把字符鏡像為一個替代的字符並刪除原來的字符或者把不再管那個字符。這個工具讀取標准的輸入並且寫入標准的輸出。
tr 工具一般與兩個參數一起使用,string1 (字符串1)和 string2 (字符串2)。每個字符在這兩個字符串中的位置是非常重要的:每一次tr發現在其輸入的string1中的一個字符的時候,它都要用 string2 中相對應的字符取代那個字符。
使用一個參數,string1 和“--delete”(刪除指令)的選項,tr 刪除在 string1 中指定的字符。這個“squeeze- repeats ”(縮減連續重復的字符)選項使用一個出現的字符取代在 string1 中連續出現的字符,例如 abbc 將變成 abc。
你可以使用一個連字符代表在 instring1 或者 string2 中的一系列字符。這兩個命令行在下面的例子中產生同樣的結果:
$ echo abcdef | tr 'abcdef' 'xyzabc'
xyzabc
$ echo abcdef | tr 'a-f' 'x-za-c'
xyzabc
下面這個例子演示了隱藏文本的流行的做法。這個方法通常稱作“ROT13”(rotate 13),因為它用第十三個字母代替第一個字母,用第十四個字母代替第二個字母,以此類推。
$ echo The punchline of the joke is ... |
> tr 'A-M N-Z a-m n-z' 'N-Z A-M n-z a-m'
Gur chapuyvar bs gur wbxr vf ...
為了使這個文本再次智能化,把給 tr 的參數順序倒過來:
$ echo Gur chapuyvar bs gur wbxr vf ... |
> tr 'N-Z A-M n-z a-m' 'A-M N-Z a-m n-z'
The punchline of the joke is ...
這個“--delete”選項使 tr 刪除選擇的字符:
$ echo If you can read this, you can spot the missing vowels! |
> tr --delete 'aeiou'
If y cn rd ths, y cn spt th mssng vwls!
在下面的例子中,tr 替換幾個字符並且產生與單個字符相同的一對兒字符:$ echo tennessee | tr --squeeze-repeats 'tnse' 'srne'
serene
下一個例子用一個“新文件”字符替換在 draft1 文件中的沒有按照字母順序排列的每一個字符。輸出是一個詞匯列表,每一行一個單詞:
$ tr --complement --squeeze-repeats '[:alpha:]' 'n' < draft1
最後一個例子是使用字符類提升那裡的字符串“hi there”:
$ echo hi there | tr '[:lower:]' '[:upper:]'
HI THERE
總結
LP:最後還有什麼想法嗎?
答:我想說命令行並不適用於每一個人。命令行適用於那些要求親手操作和對他們馴服的野獸有更強的控制力的那些用戶。學習外殼程序能夠做什麼已經成功了一半。成功的另一半是學習一些與 Linux 發布版一起推出的許多工具的知識。你不需要了解每一個指令的每一個參數。了解每一個指令名稱的含義和每個指令基本上能做什麼就足夠了。你可以閱讀我的書中有關人和信息的內容或者有關指令參考的部分。查看 tac 工具並且在一開始的時候會對這個工具名稱的起源感到可笑。