shell 补齐路径_bash shell:命令的文件名自动补全设置
大家都知道 bash
里有個文件自動補全功能,按兩下?Tab?鍵顯示出候選補全文件名,不同程序會顯示相應的文件類型(根據擴展名來判斷),例如
mplayer 會顯示媒體文件(如 avi、mpg、mkv),而不會顯示文本文件(如 txt、cfg、ini),而 Vim
則是反過來,這樣的一直以來相當好用,不過還是有些時候還是挺煩人的。
有時我想用 Vim 的 diff 功能來比較文件,比如兩個 java 的
class 文件,雖然 class 文件是二進制文件,但在 Vim 中可以轉換成十六進制來顯示,方便比較。打了 Vim
命令后,按兩下?Tab?并補全候選不會有
class 文件,所以你得手動輸入。
mplayer
的一個參數?-ass-styles,這個參數用于使用外部
ass 字幕的樣式,后面接一個 ass 文件的路徑,用樣也不會顯示出來,因為 bash 的自動補全里并沒有為這個參數定義過。
這兩個例子只是最近用到,其實一直以來也遇過這種情況,很多時候我會把按兩次?Tab?來當
ls
命令使用,看看目錄下有什么文件,但這樣會讓某些文件沒顯示出來,讓你誤以為文件不存在,當前目錄短文件名就直接輸入算了,好幾層的目錄和長文件名就麻煩,對于這種情況,我的土方法是
把打了一半的命令行?Ctrl
+ c?掉,然后用 ls 看列一下,復制粘貼路徑出來
或者先直接補全路徑后,把光標移回開頭輸入命令名
這樣太不夠效率了,尤其是在調試時,命令參數記得比路徑還要熟的,干脆關掉這個文件擴展名檢測功能好了。
我記得 bash 的補全腳本在
/etc/bash_completion,這個文件好長,稍微看了一下,發現有關聯的代碼,比如這段看來就是定義補全的擴展名
complete -f -X '!*.fig' xfig
complete -f -X '!*.@(mid?(i)|MID?(I)|cmf|CMF)' playmidi
complete -f -X '!*.@(mid?(i)|MID?(I)|rmi|RMI|rcp|RCP|[gr]36|[GR]36|g18|G18|mod|MOD|xm|XM|it|IT|x3m|X3M|kar|KAR)' timidity
complete -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' vi vim gvim rvim view rview rgvim rgview gview
complete -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' emacs
complete -f -X '!*.@(exe|EXE|com|COM|scr|SCR|exe.so)' wine
直接執行?complete?會輸出當前定義過補全的命令,看樣子也是在
/etc/bash_completion 里定義的
$ complete | grep " mplayer\| vim"
complete -o filenames -F _mplayer mplayer
complete -o filenames -F _filedir_xspec vim
man 了一下 complete 命令,沒有手冊,屬于 builtin
命令,上網找,簡介在?這里?,用法在
大概看了一下用法,就是?complete
補全行為選項 命令名
-F:執行指定函數名,候選結果保存在?COMPREPLY?數組變量里,補全功能更強大,可以實現命令參數補全,函數名在
/etc/bash_completion 定義的。
-f:補全文件名,后可跟?-X?參數。
-X:過濾表達式,符合表達式的文件名會被排除,即不會在補全候選顯示出來,如果以感嘆號開頭,則表示反轉,即符合表達式的文件名才顯示。
-o:補全類型,filenames?表示補全的是一個文件,跟?-f?參數使用才有效;其它值如?dirnames?表示補全目錄。
-F?執行的函數比?-f
-X?更早執行,這樣說起來有點混亂,我測試了一下,
當你輸入好「命令名 」,按兩下Tab鍵,開始補全。
bash
執行了?-F?指定的函數,函數執行完后輸出數組變量?COMPREPLY?的結果,這個變量值有可能為空。
繼續根據?-f
-X?里的表達式,符合表達式的文件名不則顯示,同時結果再根據?-o?指定補全類型來決定是否顯示。
就以 Vim 和 mplayer 舉例
對于 Vim 來說,它最終被定義的行為這樣
complete -o filenames -F _filedir_xspec -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' vim
先執行?_filedir_xspec?函數,而這個函數執行后變量?COMPREPLY?為空,所以什么也沒輸出。接著補全文件名,可以看?class?字符串在表達式里面,所以不顯示。如果刪掉?class|?再運行,就可以匹配
class 文件了。
對于mplayer,它最終被定義的行為這樣
complete -o filenames -F _mplayer mplayer
先執行了?_mplayer?函數,這個函數在
/etc/bash_completion 代碼非常多,mplayer 的選項參數都打上去了,所以能補全 mplayer
的選項參數。到補全文件名時,沒有指定過濾表達式,所以什么都沒做。亦即它的補全功能全由?_mplayer?函數完成。
以上結果純屬連猜帶蒙,若有錯誤,煩請指正,為了介紹一個小功能碼了這么多字容易嘛我,所以
臨時禁用 Vim 的補全功能就是
complete vim
保留路徑補全,但不要擴展名檢測,不指定「-X」即可
complete -f vim
只補全文件
complete -o filenames -f vim
只補全目錄
complete -o dirnames vim
總結
以上是生活随笔為你收集整理的shell 补齐路径_bash shell:命令的文件名自动补全设置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python调用cplex求解_CPLE
- 下一篇: idea验证失败_SVN提示https证