首頁 > 軟體

快速掌握炫酷的 Linux 命令列

2020-06-16 17:32:37

前言

  之前看到一篇介紹 IntelliJ IDEA 設定的文章,它裡面用的是 gif 動態圖片進行展示,我覺得很不錯。所以在我今天以及以後的博文中,我也會盡量使用 gif 動圖進行展示。製作 gif 動圖很花時間,為了把我的部落格打造成精品我也是蠻拼的了。使用動圖的優點是演示效果好,缺點是動圖體積過大,為了降低圖片體積,我只能降低解析度了。
  關於高效使用命令列這個話題,在網上已經是老生常談了。在本文中,也有不少我自己的觀點和體會,比如我會提到有些快捷鍵要熟記,有些則完全不需要記,畢竟我們的記憶力也是有限的,我還會提到一些助記的方法。所以,本文絕對不是照本宣科,值得大家擁有,請大家一定記得點讚。

使用 tmux 復用控制台視窗

  高效使用命令列的首要原則就是要盡量避免非命令列的干擾,甚麼意思呢?就是說一但開啟了一個控制台視窗,就盡量不要再在桌面上切換來切換去了,不要一會兒被別的視窗擋住控制台,一會兒又讓別的視窗破壞了控制台的背景,最好是把控制台最大化或全螢幕,最好連滑鼠都不要用。只有這樣,才能達到比較高的效率。但是在實際工作中,我們又經常需要同時在多個控制台中進行工作,例如:在一個控制台中執行錄製螢幕的命令,在另外一個控制台中工作,或者在一個控制台中工作,在另外一個控制台中閱讀文件。如果既想在多個控制台中工作,又不想一大堆視窗擋來擋去、換來換去的話,就可以考慮試試 tmux 了。如下圖:

  tmux 的功能很多,什麼 Session 啊、Detach 啊、Atach 啊什麼的我們暫時不用去關心,只用好它的控制台視窗複用功能就行了。tmux 中有 window 和 pane 的概念,tmux 可以建立多個 window,這些 window 是不會互相遮擋的,每次只顯示一個 window,其它的 window 會自動隱藏,可以使用快捷鍵在 window 之間切換。同時,可以把一個 window 切分成多個 pane,這些 pane 同時顯示在螢幕上,可以使用快捷鍵在 pane 之間切換。

  tmux 的快捷鍵很多,要想全面了解 tmux 的最好辦法當然是閱讀 tmux 的文件了,使用命令 man tmux 就可以了。但是我們只需要記住少數幾個重要的快捷鍵就可以了,如下表:

快捷鍵功能
Ctrl+B c 建立一個 window
Ctrl+B [n][p] 切換到下一個視窗或上一個視窗
Ctrl+B & 關閉當前視窗
Ctrl+B " 將當前 window 或 pane 切分成兩個 pane,上下排列
Ctrl+B % 將當前 window 或 pane 切分成兩個 pane,左右排列
Ctrl+B x 關閉當前 pane
Ctrl+B [↑][↓][←][→] 在 pane 之間移動
Ctrl+[↑][↓][←][→] 調整當前 pane 的大小,一次調整一格
Alt+[↑][↓][←][→] 調整當前 pane 的大小,一次調整五格

  tmux 的快捷鍵比較特殊,除了調整 pane 大小的快捷鍵之外,其它的都是先按 Ctrl+B,再按一個字元。先按 Ctrl+B,再按 c,就會建立一個 window,這裡 c 就是 create window。先按 Ctrl+B,再按 n 或者 p,就可以在視窗之間切換,它們是 next window 和 previous window 的意思。關閉視窗是先按 Ctrl+B,再按 &,這個只能死記。先按 Ctrl+B,再按 " ,表示上下拆分視窗,可以想象成單引號和雙引號在鍵盤上是上下舖關係。先按 Ctrl+B,再按 % 表示左右拆分視窗,大概是因為百分數都是左右書寫的吧。至於在 pane 之間移動和調整 pane 大小的方向鍵,就不用多說了吧。

在命令列中快速移動游標

  在命令列中輸入命令時,經常要在命令列中移動游標。這個很簡單嘛,使用左右方向鍵就可以了,但是有時候我們輸入了很長一串命令,卻突然要修改這個命令最開頭的內容,如果使用向左的方向鍵一個字元一個字元地把游標移到命令的開頭,是否太慢了呢?有時我們需要直接在命令的開頭和結尾之間切換,有時又需要能夠一個單詞一個單詞地移動游標,在命令列中,其實這都不是事兒。如下圖:

  這幾種移動方式都是有快捷鍵的。其實一個字元一個字元地移動游標也有快捷鍵 Ctrl+B 和 Ctrl+F,但是這兩個快捷鍵我們不需要記,有什麼能比左右方向鍵更方便的呢?我們真正要記的是下面這幾個:

快捷鍵功能
Ctrl + A 將游標移動到命令列的開頭
Ctrl + E 將游標移動到命令列的結尾
Alt + B 將游標向左移動一個單詞
Alt + F 將游標向右移動一個單詞

  這幾個快捷鍵太好記了,A 代表 ahead,E 代表 end,B 代表 back,F 代表 forward。為什麼按單詞移動游標的快捷鍵都是以 Alt 開頭呢?那是因為按字元移動游標的快捷鍵把 Ctrl 佔用了。但是按字元移動游標的快捷鍵我們用不到啊,因為我們有左右方向鍵啊。

在命令列中快速刪除文字

  對輸入的內容進行修改也是我們經常要幹的事情,對命令列進行修改就涉及到先刪除一部分內容,再輸入新內容。我們碰到的情況是有時候只需要修改個別字元,有時候需要修改個別單詞,而有時候,輸入了半天的很長的一段命令,我們說不要就全都不要了,整行刪除。常用的刪除鍵當然是 BackSpace 和 Delete 啦,不過一次刪除一個字元,是否太慢了呢?那麼,請熟記以下幾個快捷鍵吧:

快捷鍵功能
Ctrl + U 刪除從游標到行首的所有內容,如果游標在行尾,自然就整行都刪除了啊
Ctrl + K 刪除從游標到行尾的所有內容,如果游標在行首,自然也是整行都刪除了啊
Ctrl + W 刪除游標前的一個單詞
Alt + D 刪除游標後的一個單詞
Ctrl + Y 將剛刪除的內容貼上到游標處,有時候刪錯了可以用這個快捷鍵恢復刪除的內容

  效果請看下圖:

  這幾個快捷鍵也是蠻好記的,U 代表 undo,K 代表 kill,W 代表 word,D 代表 delete, Y 代表 yank。其中比較奇怪的是 Alt+D 又是以 Alt 開頭的,那是因為 Ctrl+D 又被佔用了。Ctrl+D 有幾個意思,在編輯命令列的時候它代表刪除一個字元,當然,這個快捷鍵其實我們用不到,因為 BackSpace 和 Delete 方便多了。在某些程式從 stdin 讀取資料的時候,Ctrl+D 代表 EOF,這個我們偶爾會用到。

快速檢視和搜尋歷史命令

  對於曾經執行過的命令,除非特別短,我們一般不會重複輸入,從歷史記錄中找出來用自然要快得多。我們用得最多的就是 ↑ 和 ↓,特別是不久前才剛剛輸入過的命令,使用 ↑ 向上翻幾行就找到了,按一下 Enter 就執行,多舒服。但是有時候,明明記得是不久前才用過的命令,但是向上翻了半天也沒找到,怎麼辦?那只好使用 history 命令來檢視所有的歷史記錄了。歷史記錄又特別長,怎麼辦?可以使用 history | lesshistory | grep '...'。但是還有終極大殺招,那就是按 Ctrl+R 從歷史記錄中進行搜尋。按了 Ctrl+R 之後,每輸入一個字元,都會和歷史記錄中進行增量匹配,輸入得越多,匹配越精確。當然,有時候含有相同搜尋字串的命令特別多,怎麼辦?繼續按 Ctrl+R,就會繼續搜尋下一條匹配的歷史記錄。如下圖:

  這裡,需要記住的命令和快捷鍵如下表:

命令或快捷鍵功能
history 檢視歷史記錄
history | less 分頁檢視歷史記錄
history | grep '...' 在歷史記錄中搜尋匹配的命令,並顯示
Ctrl + R 逆向搜尋歷史記錄,和輸入的字元進行增量匹配
Esc 停止搜尋歷史記錄,並將當前匹配的結果放到當前輸入的命令列上
Enter 停止搜尋歷史記錄,並將當前匹配的結果立即執行
Ctrl + G 停止搜尋歷史記錄,並放棄當前匹配的結果
Alt + > 將歷史記錄中的位置標記移動到歷史記錄的尾部

?? 這裡需要注意的是,當我們在歷史記錄中搜尋的時候,是有位置標記的,Ctrl+R 是指從當前位置開始,逆向搜尋,R 代表的是 reverse,每搜尋一條記錄,位置標記都會向歷史記錄的頭部移動,下次搜尋又從這裡開始繼續向頭部搜尋。所以,我們一定要記住快捷鍵 Alt+>,它可以把歷史記錄的位置標記還原。另外需要注意的是停止搜尋歷史記錄的快捷鍵有三個,如果按 Enter 鍵,匹配的命令就立即執行了,如果你還想有修改這條命令的機會的話,一定不要按 Enter,而要按 Esc。如果什麼都不想要,就按 Ctrl+G 吧,它會還你一個空白的命令列。

快速參照和修飾歷史命令

  除了檢視和搜尋歷史記錄,我們還可以以更靈活的方式參照歷史記錄中的命令。常見的簡單的例子有 !! 代表參照上一條命令,!$代表參照上一條命令的最後一個引數,^oldstring^newstring^代表將上一條命令中的 oldstring 替換成 newstring。這些操作是我們平時使用命令列的時候的一些常用技巧,其實它們的本質,是由 history 庫提供的 history expansion 功能。Bash 使用了 history 庫,所以也能使用這些功能。其完整的文件可以檢視 man history 手冊頁。知道了 history expansion 的理論,我們還可以做一些更加複雜的操作,如下圖:

  參照和修飾歷史命令的完整格式是這樣的:

![!|[?]string|[-]number]:[n|x-y|^|$|*|n*|%]:[h|t|r|e|p|s|g]

  可以看到,一個對歷史命令的參照被 : 分為了三個部分,第一個部分決定了參照哪一條歷史命令;第二部分決定了選取該歷史命令中的第幾個單詞,單詞是從0開始編號的,也就是說第0個單詞代表命令本身,第1個到最後一個單詞代表命令的引數;第三部分決定了對選取的單詞如何修飾。下面我列出完整表格:

  表格一、參照哪一條歷史命令:

操作符功能
! 所有對歷史命令的參照都以 ! 開始,除了 ^oldstring^newstring^ 形式的快速替換
!n 參照第 n 條歷史命令
!-n 參照倒數第 n 條歷史命令
!! 參照上一條命令,等於 !-1
!string 逆向搜尋歷史記錄,第一條以 string 開頭的命令
!?string[?] 逆向搜尋歷史記錄,第一條包含 string 的命令
^oldstring^newstring^ 對上一條命令進行快速替換,將 oldstring 替換為 newstring
!# 參照當前輸入的命令

  表格二、選取哪一個單詞:

操作符功能
0 第0個單詞,在 shell 中就是命令本身
n 第n個單詞
^ 第1個單詞,使用 ^ 時可以省略前面的冒號
$ 最後一個單詞,使用 $ 是可以省略前面的冒號
% 和 ?string? 匹配的單詞,可以省略前面的冒號
x-y 從第 x 個單詞到第 y 個單詞,-y 代表 0-y
* 除第 0 個單詞外的所有單詞,等於 1-$
x* 從第 x 個單詞到最後一個單詞,等於 x-$,可以省略前面的冒號
x- 從第 x 個單詞到倒數第二個單詞

  表格三、對選取的單詞做什麼修飾:

操作符功能
h 選取路徑開頭,不要檔名
t 選取路徑結尾,只要檔名
r 選取檔名,不要擴充套件名
e 選取擴充套件名,不要檔名
s/oldstring/newstring/ 將 oldstring 替換為 newstring
g 全域性替換,和 s 配合使用
p 只列印修飾後的命令,不執行

  這幾個命令其實挺好記的,h 代表 head,只要路徑開頭不要檔名,t 代表 tail,只要路徑結尾的檔名,r 代表 realname,只要檔名不要擴充套件名,e 代表 extension,只要擴充套件名不要檔名,s 代表 substitute,執行替換功能,g 代表 global,全域性替換,p 代表 print,只列印不執行。有時候光使用 :p 還不夠,我們還可以把這個經過參照修飾後的命令直接在當前命令列上展開而不立即執行,它的快捷鍵是:

操作符功能
Ctrl + Alt + E 在當前命令列上展開歷史命令參照,展開後不立即執行,可以修改,按 Enter 後才會執行
Alt + ^ 和上面的功能一樣

  這兩個快捷鍵,記住一個就行。這樣,當我們對歷史命令的參照修飾完成後,可以先展開來看一看,如果正確再執行。眼見為實嘛,反正我是每次都展開看看才放心。

更多詳情見請繼續閱讀下一頁的精彩內容http://www.linuxidc.com/Linux/2016-09/135358p2.htm


IT145.com E-mail:sddin#qq.com