Linux Shell 命令自動補全(各方資料彙總補全版)

在下所在的公司定義了一種路徑,配合自定義的 loader 命令;遂命令在下完成自定義路徑的自動補全需求。

關於Linux Shell命令自動補全已有的一些優秀 blog

本人遇到的一些需求及解決方案:

需求一:從多個路徑下獲取補全候選項,並做去重
  • 解決方案寫一個循環獲取所有候選項,並且去重。這裏記錄一下 shell數組去重 ,和數組的使用。
array=()
array[0]="hello"
array[1]="hello"
# 數組去重(從一個貼吧裏找到的,非原創)
array=($(awk -vRS=' ' '!a[$1]++' <<< ${array[@]}))

# 數組的使用(同樣非原創,找不到鏈接了)
COMPREPLY=($(compgen -W "${array[*]}" -- "he"))
需求二:自定義路徑 轉化成 系統路徑
  • 比如:我需要把 test:hello.world 轉成 /.../hello/world
  • 這裏需要注意的:COMP_WORDS 切割方式是按 COMP_WORDBREAKS 進行切割的。所以 test:hello.world 會被當成三個單詞 test:hello.world;所以 COMP_CWORD 會增加得比較快。(都是坑=_=)
[root@localhost ~]# echo $COMP_WORDBREAKS
"'@><=;|&(:
  • 所以就有人有這樣的需求:刪除或者添加 COMP_WORDBREAKS,比如,我希望 . 當成分隔符,或者我希望 : 不是分割符。注意:千萬別去改COMP_WORDBREAKS。這裏首推 StackOverflow 的帖子,好久遠的帖子了。
    • 對於刪除分隔符,使用 _get_comp_words_by_ref -n : xxxxx 就可以把因 : 分割的單詞拼起來。大家可以百度一下 _get_comp_words_by_ref 這個關鍵字,印象中有人詳解過。
    • 對於添加分隔符,我參考了LinuxQuestions的帖子。思路是,自己把 . 作爲分隔符切分,然後作爲前綴在單詞補全後補上,同時對於其他特殊字符,也可以作爲後綴補上。
local pro=($(pwd))
local prefix=${cur%%.*}
cd $dict_path"/"$prefix
compopt -o nospace
COMPREPLY=( $(compgen -S "#" -P $prefix"." -d -f -- ${cur#*"."}) )
cd $pro
  • 將 cur 從右邊數最後一個 . 的左邊的內容作爲前綴,利用 compgen-P 參數,這是增加前綴的參數。如果不加前綴,就會出現 test.f ,你希望 f 補全爲 father,整體變成 test.father,這是你希望得到的。請注意,補全是整個單詞補全,所以沒有前綴的情況下,test.是會被刪掉的,你只能得到 father ,所以 test. 必須首先抽出來當做前綴,然後補全得到 father 後拼到前面得到 test.father。(在下語文水平不好,希望描述清楚了這個巨坑)。同理,補全是補全單詞,不會帶像 cd 命令一樣的 /,所以如果想自動補全 /,使用 -S 參數,增加後綴(代碼中我增加了 # 後綴)。
  • compopt -o nospace 是將補全後自動加的空格刪掉。
補充:/etc/bash_completion.d 目錄下的補全腳本不生效

結束語

折騰了兩天,全程 tab 起飛,放飛自我。當然其中還學習了一些 shell 命令的基本寫法,假裝自己是運維。路漫漫其修遠兮,加油加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章