開玩笑地說,我經(jīng)常把 Unix 描述為“這個操作系統(tǒng)是為喜歡敲鍵盤的人們服務的。” 當然,Unix 甚至還有一個命令行,這個事實是個確鑿的證據(jù),證明了我所說的話。 但是命令行用戶不喜歡敲入那么多字。那又為什么如此多的命令會有這樣簡短的命令名,像 cp,ls,mv,和 rm?事實上,命令行最為珍視的目標之一就是懶惰;用最少的擊鍵次數(shù) 來完成最多的工作。另一個目標是你的手指永遠不必離開鍵盤,永不觸摸鼠標。在這一 章節(jié),我們將看一下 bash 特性,這些特性使鍵盤使用起來更加迅速,更加高效。
以下命令將會露面:
clear - 清空屏幕
Bash 使用了一個名為 Readline 的庫(共享的線程集合,可以被不同的程序使用), 來實現(xiàn)命令行編輯。我們已經(jīng)看到一些例子。我們知道,例如,箭頭按鍵可以移動鼠標, 此外還有許多特性。想想這些額外的工具,我們可以在工作中使用。學會所有的特性 并不重要,但許多特性非常有幫助。選擇自己需要的特性。
注意:下面一些按鍵組合(尤其使用 Alt 鍵的組合),可能會被 GUI 攔截來觸發(fā)其它的功能。 當使用虛擬控制臺時,所有的按鍵組合都應該正確地工作。
下表列出了移動光標所使用的按鍵:
| 按鍵 | 行動 |
|---|---|
| Ctrl-a | 移動光標到行首。 |
| Ctrl-e | 移動光標到行尾。 |
| Ctrl-f | 光標前移一個字符;和右箭頭作用一樣。 |
| Ctrl-b | 光標后移一個字符;和左箭頭作用一樣。 |
| Alt-f | 光標前移一個字。 |
| Alt-b | 光標后移一個字。 |
| Ctrl-l | 清空屏幕,移動光標到左上角。clear 命令完成同樣的工作。 |
表9-2列出了鍵盤命令,這些命令用來在命令行中編輯字符。
| 按鍵 | 行動 |
|---|---|
| Ctrl-d | 刪除光標位置的字符。 |
| Ctrl-t | 光標位置的字符和光標前面的字符互換位置。 |
| Alt-t | 光標位置的字和其前面的字互換位置。 |
| Alt-l | 把從光標位置到字尾的字符轉(zhuǎn)換成小寫字母。 |
| Alt-u | 把從光標位置到字尾的字符轉(zhuǎn)換成大寫字母。 |
Readline 的文檔使用術(shù)語 killing 和 yanking 來指我們平常所說的剪切和粘貼。 剪切下來的本文被存儲在一個叫做剪切環(huán)(kill-ring)的緩沖區(qū)中。
| 按鍵 | 行動 |
|---|---|
| Ctrl-k | 剪切從光標位置到行尾的文本。 |
| Ctrl-u | 剪切從光標位置到行首的文本。 |
| Alt-d | 剪切從光標位置到詞尾的文本。 |
| Alt-Backspace | 剪切從光標位置到詞頭的文本。如果光標在一個單詞的開頭,剪切前一個單詞。 |
| Ctrl-y | 把剪切環(huán)中的文本粘貼到光標位置。 |
元鍵
如果你冒險進入到 Readline 的文檔中,你會在 bash 手冊頁的 READLINE 段落, 遇到一個術(shù)語"元鍵"(meta key)。在當今的鍵盤上,這個元鍵是指 Alt 鍵,但 并不總是這樣。
回到昏暗的年代(在 PC 之前 Unix 之后),并不是每個人都有他們自己的計算機。 他們可能有一個叫做終端的設備。一個終端是一種通信設備,它以一個文本顯示 屏幕和一個鍵盤作為其特色,它里面有足夠的電子器件來顯示文本字符和移動光標。 它連接到(通常通過串行電纜)一個更大的計算機或者是一個大型計算機的通信 網(wǎng)絡。有許多不同的終端產(chǎn)品商標,它們有著不同的鍵盤和特征顯示集。因為它們 都傾向于至少能理解 ASCII,所以軟件開發(fā)者想要符合最低標準的可移植的應用程序。 Unix 系統(tǒng)有一個非常精巧的方法來處理各種終端產(chǎn)品和它們不同的顯示特征。因為 Readline 程序的開發(fā)者們,不能確定一個專用多余的控制鍵的存在,他們發(fā)明了一個 控制鍵,并把它叫做"元"("meta")。然而在現(xiàn)代的鍵盤上,Alt 鍵作為元鍵來服務。 如果你仍然在使用終端(在 Linux 中,你仍然可以得到一個終端),你也可以按下和 釋放 Esc 鍵來得到如控制 Alt 鍵一樣的效果。
shell 能幫助你的另一種方式是通過一種叫做自動補全的機制。當你敲入一個命令時, 按下 tab 鍵,自動補全就會發(fā)生。讓我們看一下這是怎樣工作的。給出一個看起來 像這樣的家目錄:
[me@linuxbox ~]$ ls
Desktop ls-output.txt Pictures Templates Videos
....
試著輸入下面的命令,但不要按下 Enter 鍵:
[me@linuxbox ~]$ ls l
現(xiàn)在按下 tab 鍵:
[me@linuxbox ~]$ ls ls-output.txt
看一下 shell 是怎樣補全這一行的?讓我們再試試另一個例子。這回,也 不要按下 Enter:
[me@linuxbox ~]$ ls D
按下 tab:
[me@linuxbox ~]$ ls D
沒有補全,只是嘟嘟響。因為"D"不止匹配目錄中的一個條目。為了自動補全執(zhí)行成功, 你給它的"線索"必須不模棱兩可。如果我們繼續(xù)輸入:
[me@linuxbox ~]$ ls Do
然后按下 tab:
[me@linuxbox ~]$ ls Documents
自動補全成功了。
這個實例展示了路徑名自動補全,這是最常用的形式。自動補全也能對變量起作用(如果 字的開頭是一個"$"),用戶名字(單詞以"~"開始),命令(如果單詞是一行的第一個單詞), 和主機名(如果單詞的開頭是"@")。主機名自動補全只對包含在文件/etc/hosts 中的主機名有效。
有一系列的控制和元鍵序列與自動補全相關(guān)聯(lián):
| 按鍵 | 行動 |
|---|---|
| Alt-? | 顯示可能的自動補全列表。在大多數(shù)系統(tǒng)中,你也可以完成這個通過按 兩次 tab 鍵,這會更容易些。 |
| Alt-* | 插入所有可能的自動補全。當你想要使用多個可能的匹配項時,這個很有幫助。 |
可編程自動補全
目前的 bash 版本有一個叫做可編程自動補全工具??删幊套詣友a全允許你(更可能是,你的 發(fā)行版提供商)來加入額外的自動補全規(guī)則。通常需要加入對特定應用程序的支持,來完成這個 任務。例如,有可能為一個命令的選項列表,或者一個應用程序支持的特殊文件類型加入自動補全。 默認情況下,Ubuntu 已經(jīng)定義了一個相當大的規(guī)則集合??删幊套詣友a全是由 shell 函數(shù)實現(xiàn)的,shell 函數(shù)是一種小巧的 shell 腳本,我們會在后面的章節(jié)中討論到。如果你感到好奇,試一下:
set | less
查看一下如果你能找到它們的話。默認情況下,并不是所有的發(fā)行版都包括它們。
正如我們在第二章中討論到的,bash 維護著一個已經(jīng)執(zhí)行過的命令的歷史列表。這個命令列表 被保存在你家目錄下,一個叫做 .bash_history 的文件里。這個 history 工具是個有用資源, 因為它可以減少你敲鍵盤的次數(shù),尤其當和命令行編輯聯(lián)系起來時。
在任何時候,我們都可以瀏覽歷史列表的內(nèi)容,通過:
[me@linuxbox ~]$ history | less
在默認情況下,bash 會存儲你所輸入的最后 500 個命令。在隨后的章節(jié)里,我們會知道 怎樣調(diào)整這個數(shù)值。比方說我們想要找到列出目錄 /usr/bin 內(nèi)容的命令。一種方法,我們可以這樣做:
[me@linuxbox ~]$ history | grep /usr/bin
比方說在我們的搜索結(jié)果之中,我們得到一行,包含了有趣的命令,像這樣;
88 ls -l /usr/bin > ls-output.txt
數(shù)字 "88" 是這個命令在歷史列表中的行號。隨后在使用另一種展開類型時,叫做 歷史命令展開,我們會用到這個數(shù)字。我們可以這樣做,來使用我們所發(fā)現(xiàn)的行:
[me@linuxbox ~]$ !88
bash 會把 "!88" 展開成為歷史列表中88行的內(nèi)容。還有其它的歷史命令展開形式,我們一會兒 討論它們。bash 也具有按遞增順序來搜索歷史列表的能力。這意味著隨著字符的輸入,我們 可以告訴 bash 去搜索歷史列表,每一個附加字符都進一步提煉我們的搜索。啟動遞增搜索, 輸入 Ctrl-r,其后輸入你要尋找的文本。當你找到它以后,你可以敲入 Enter 來執(zhí)行命令, 或者輸入 Ctrl-j,從歷史列表中復制這一行到當前命令行。再次輸入 Ctrl-r,來找到下一個 匹配項(向上移動歷史列表)。輸入 Ctrl-g 或者 Ctrl-c,退出搜索。實際來體驗一下:
[me@linuxbox ~]$
首先輸入 Ctrl-r:
(reverse-i-search)`':
提示符改變,顯示我們正在執(zhí)行反向遞增搜索。搜索過程是"反向的",因為我們按照從"現(xiàn)在"到過去 某個時間段的順序來搜尋。下一步,我們開始輸入要查找的文本。在這個例子里是 "/usr/bin":
(reverse-i-search)`/usr/bin': ls -l /usr/bin > ls-output.txt
即刻,搜索返回我們需要的結(jié)果。我們可以執(zhí)行這個命令,按下 Enter 鍵,或者我們可以復制 這個命令到我們當前的命令行,來進一步編輯它,輸入 Ctrl-j。復制它,輸入 Ctrl-j:
[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt
我們的 shell 提示符重新出現(xiàn),命令行加載完畢,正準備行動!下表列出了一些按鍵組合, 這些按鍵用來操作歷史列表:
| 按鍵 | 行為 |
|---|---|
| Ctrl-p | 移動到上一個歷史條目。類似于上箭頭按鍵。 |
| Ctrl-n | 移動到下一個歷史條目。類似于下箭頭按鍵。 |
| Alt- | 移動到歷史列表開頭。 |
| Alt-> | 移動到歷史列表結(jié)尾,即當前命令行。 |
| Ctrl-r | 反向遞增搜索。從當前命令行開始,向上遞增搜索。 |
| Alt-p | 反向搜索,不是遞增順序。輸入要查找的字符串,然后按下 Enter,執(zhí)行搜索。 |
| Alt-n | 向前搜索,非遞增順序。 |
| Ctrl-o | 執(zhí)行歷史列表中的當前項,并移到下一個。如果你想要執(zhí)行歷史列表中一系列的命令,這很方便。 |
通過使用 "!" 字符,shell 為歷史列表中的命令,提供了一個特殊的展開類型。我們已經(jīng)知道一個感嘆號 ,其后再加上一個數(shù)字,可以把來自歷史列表中的命令插入到命令行中。還有一些其它的展開特性:
| 序列 | 行為 |
|---|---|
| !! | 重復最后一次執(zhí)行的命令。可能按下上箭頭按鍵和 enter 鍵更容易些。 |
| !number | 重復歷史列表中第 number 行的命令。 |
| !string | 重復最近歷史列表中,以這個字符串開頭的命令。 |
| !?string | 重復最近歷史列表中,包含這個字符串的命令。 |
應該小心謹慎地使用 "!string" 和 "!?string" 格式,除非你完全確信歷史列表條目的內(nèi)容。
在歷史展開機制中,還有許多可利用的特點,但是這個題目已經(jīng)太晦澀難懂了, 如果我們再繼續(xù)討論的話,我們的頭可能要爆炸了。bash 手冊頁的 HISTORY EXPANSION 部分詳盡地講述了所有要素。
腳本
除了 bash 中的命令歷史特性,許多 Linux 發(fā)行版包括一個叫做 script 的程序, 這個程序可以記錄整個 shell 會話,并把 shell 會話存在一個文件里面。這個命令的基本語法是:
script [file]
命令中的 file 是指用來存儲 shell 會話記錄的文件名。如果沒有指定文件名,則使用文件 typescript。查看腳本的手冊頁,可以得到一個關(guān)于 script 程序選項和特點的完整列表。
在這一章中,我們已經(jīng)討論了一些由 shell 提供的鍵盤操作技巧,這些技巧是來幫助打字員減少工作量的。 隨著時光流逝,你和命令行打交道越來越多,我猜想你會重新翻閱這一章的內(nèi)容,學會更多的技巧。 目前,你就認為它們是可選的,潛在地有幫助的。
Wikipedia 上有一篇關(guān)于計算機終端的好文章: