Linux命令列自動補全功能詳解(範例演示)

2020-07-16 10:05:07
檔名(或者目錄名)是執行 Linux 命令中最常見的引數,例如前面介紹的 cd、mkdir、cp 等命令,都涉及到了檔名。然而對初學者來說,輸入完整的檔名感覺很麻煩,尤其面臨檔名(目錄名)特別長的時候。

考慮到這種情況,Shell(Bash)提供了一種稱為“命令列自動補全”的功能,即在輸入檔名的時候,只需要輸入該檔名的前幾個字元,然後按 Tab 鍵,Shell 就可以自動將檔名補全。

舉個例子,在 /etc 目錄下,執行如下命令:

[[email protected] ~]# cd /etc
[[email protected] etc]# cd fs <-- 按一次 Tab 鍵

當按下 Tab 鍵時,你會發現 Shell 自動將 "fs" 補全成了 "fatab",這是因為當前 /etc 目錄中只有 fstab 是以 "fs" 開頭,因此 Shell 可以確定這裡想要輸入的檔名稱為 fstab。

那麼,如果當前目錄中含有多個以指定字元(或字串)開頭的目錄或檔案,Shell 還可以成功辨認嗎?答案是否定的,但它會以列表的形式給出所有以指定字元或字串開頭的檔案或目錄,供使用者選擇。

例如,還是在 /etc 目錄下,執行如下命令:
[[email protected] etc]# cd b <-- 連續按兩次 Tab 鍵
bash_completion.d/      blkid/          bonobo-activation/
bashrc                  bluetooth
可以看到,當按一次 Tab 鍵時,Shell 沒有任何反映,原因就是當前目錄下以 "b" 為開頭的檔案或目錄有多個(2 個以上),僅憑一個字元 "b" 無法精準判斷出具體指的是哪個檔案。而當再一次按下 Tab 鍵時,Shell 會列表的形式顯示給使用者當前目錄下所有以 "b" 開頭的檔案或目錄。

事實上,Shell 提供的命令列補全功能不僅適用於補全檔名,也同樣適用於所有 Linux 命令。舉個例子,當輸入 ca 並連續按下 2 次 Tab 鍵時,Shell 會羅列出所有以 "ca" 開頭的 Linux 命令,如下所示:
[[email protected] etc]# ca <--連續按兩次 Tab 鍵
cacertdir_rehash    cache_restore       capsh       catchsegv
cache_check         cal                 captoinfo
cache_dump          caller              case
cache_repair        canberra-gtk-play   cat
另外,Shell 還有一套被稱作萬用字元的轉用符號(如表 1 所示),這些萬用字元可以搜尋並匹配檔名的一部分,從而大大簡化了檔名的輸入。

表 1 Shell 萬用字元及其作用
符號 作用
* 匹配任意數量的字元。
? 匹配任意一個字元。
[] 匹配括號內的任意一個字元,甚至 [] 中還可以包含用 -(短橫線)連線的字元或數位,表示一定範圍內的字元或數位。

為了學習這些萬用字元的用法,首先需要建立一個空目錄(如 test),並在該目錄中建立一些檔案(供測試用),執行命令如下:

[[email protected] etc]# makdir test
[[email protected] etc]# cd test
[[email protected] test]# touch apple banana grape grapefruit watermelon
[[email protected] test]# ls
apple banana grape grapefruit watermelon


在此基礎上,繼續執行如下命令:

[[email protected] test]# ls a* <--匹配所有以 a 字元開頭的檔名
apple
[[email protected] test]# ls g*t <--匹配所有以 g 字元開頭,以 t 字元結尾的檔名
grapefruit
[[email protected] test]# ls *e* <--匹配所有包含 e 字元的檔名
apple grape grapefruit watermelon
[[email protected] test]# ls *n* <--匹配所有包含 n 字元的檔名
banana watermelon

結合以上範例,因為 * 可以匹配任何數量的字元,因此可以一一實現範例中標注的功能。

接下來,列舉一下使用 ? 匹配檔名的範例:

[[email protected] test]# ls ????e
apple grape
[[email protected] test]# ls g???e*
grape grapefruit

因為 1 個 ? 只能匹配 1 個任意字元,因此該範例中第一個例子表示的是匹配任意包含 5 個字元但以 e 結尾的檔案(apple 和 grape),第二例子表示匹配任何以 g 開頭且第 5 個字元為 e 的檔案(grape 和 grapefruit)。

最後,列舉一些使用括號 [] 匹配檔名的範例:

[[email protected] test]# ls [abw]*
apple banana watermelon
[[email protected] test]# ls [agw]*[ne]
apple grape watermelon

此範例中,第一個例子表示匹配任何以 a、b 或 w 開頭的檔案;第二個例子中表示匹配任何以 a、g、w 開頭,以 n 或 e 結尾的檔名。

不僅如此,[] 中還可以通過 -(短橫線)表示一定範圍內的任意字元(或數位),例如:

[[email protected] test]# ls [a-g]*
apple banana grape grapefruit

其中,[a-g]* 表示匹配以字母 a 到  g 之間任何一個字母開頭的檔名。