開玩笑地說,我經(jīng)常把 Unix 描述為“這個操作系統(tǒng)是為喜歡敲鍵盤的人們服務(wù)的。” 當然,Unix 甚至還有一個命令行,這個事實是個確鑿的證據(jù),證明了我所說的話。 但是命令行用戶不喜歡敲入那么多字。那又為什么如此多的命令會有這樣簡短的命令名,像 cp,ls,mv,和 rm?事實上,命令行最為珍視的目標之一就是懶惰;用最少的擊鍵次數(shù) 來完成最多的工作。另一個目標是你的手指永遠不必離開鍵盤,永不觸摸鼠標。在這一 章節(jié),我們將看一下 bash 特性,這些特性使鍵盤使用起來更加迅速,更加高效。
以下命令將會露面:
clear - 清空屏幕
Bash 使用了一個名為 Readline 的庫(共享的線程集合,可以被不同的程序使用), 來實現(xiàn)命令行編輯。我們已經(jīng)看到一些例子。我們知道,例如,箭頭按鍵可以移動鼠標, 此外還有許多特性。想想這些額外的工具,我們可以在工作中使用。學(xué)會所有的特性 并不重要,但許多特性非常有幫助。選擇自己需要的特性。
注意:下面一些按鍵組合(尤其使用 Alt 鍵的組合),可能會被 GUI 攔截來觸發(fā)其它的功能。 當使用虛擬控制臺時,所有的按鍵組合都應(yīng)該正確地工作。
下表列出了移動光標所使用的按鍵:
按鍵 | 行動 |
---|---|
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 之后),并不是每個人都有他們自己的計算機。 他們可能有一個叫做終端的設(shè)備。一個終端是一種通信設(shè)備,它以一個文本顯示 屏幕和一個鍵盤作為其特色,它里面有足夠的電子器件來顯示文本字符和移動光標。 它連接到(通常通過串行電纜)一個更大的計算機或者是一個大型計算機的通信 網(wǎng)絡(luò)。有許多不同的終端產(chǎn)品商標,它們有著不同的鍵盤和特征顯示集。因為它們 都傾向于至少能理解 ASCII,所以軟件開發(fā)者想要符合最低標準的可移植的應(yīng)用程序。 Unix 系統(tǒng)有一個非常精巧的方法來處理各種終端產(chǎn)品和它們不同的顯示特征。因為 Readline 程序的開發(fā)者們,不能確定一個專用多余的控制鍵的存在,他們發(fā)明了一個 控制鍵,并把它叫做"元"("meta")。然而在現(xiàn)代的鍵盤上,Alt 鍵作為元鍵來服務(wù)。 如果你仍然在使用終端(在 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ī)則。通常需要加入對特定應(yīng)用程序的支持,來完成這個 任務(wù)。例如,有可能為一個命令的選項列表,或者一個應(yīng)用程序支持的特殊文件類型加入自動補全。 默認情況下,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,從歷史列表中復(fù)制這一行到當前命令行。再次輸入 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 鍵,或者我們可以復(fù)制 這個命令到我們當前的命令行,來進一步編輯它,輸入 Ctrl-j。復(fù)制它,輸入 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ù)字,可以把來自歷史列表中的命令插入到命令行中。還有一些其它的展開特性:
序列 | 行為 |
---|---|
!! | 重復(fù)最后一次執(zhí)行的命令??赡馨聪律霞^按鍵和 enter 鍵更容易些。 |
!number | 重復(fù)歷史列表中第 number 行的命令。 |
!string | 重復(fù)最近歷史列表中,以這個字符串開頭的命令。 |
!?string | 重復(fù)最近歷史列表中,包含這個字符串的命令。 |
應(yīng)該小心謹慎地使用 "!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)容,學(xué)會更多的技巧。 目前,你就認為它們是可選的,潛在地有幫助的。
Wikipedia 上有一篇關(guān)于計算機終端的好文章: