開始開發以後,才發現這真的是 bash 自己提供的功能,相關產生名單的機制他也有指令可以幫你做好。
其實一般而言,要補完的東西不外乎這幾樣:
- 檔名 & 目錄
- 可用的命令與參數
- 連線的機器
另外要熟悉的是在 bash script 中,陣列的操作方式。
如何使用 compgen
語法
compgen [參數] [清單] -- [目前已經輸入的內容]
補完自訂清單 (-W)
這是最常使用的功能。假設你有以下四個指令 list arg1 arg2 ls。你目前已經輸入 arg。那可以在 bash 環境下面試試看:
$ compgen -W "list arg1 arg2 ls" -- arg
arg1
arg2
$
補完目錄 (-d)
假設你有 dir1/ 和 dir2/ 兩個目錄,目前已經輸入 di。可以在 bash 環境下試試看:
$ compgen -d -- di
dir2
dir1
$
補完檔案 (-f)
假設目前有這六個檔案 file11 file12 file21 file22 text1.txt text2.txt。可以在 bash 環境下試試:
- 列出 file 開頭檔案: compgen -f -- file
- 列出 txt 副檔名的檔案: compgen -f -X '!*.txt' --
補完機器清單 (-A)
- 建立一個機器清單文字檔,一行一個 hostname。假設我們有以下機器:
- host11.test.com
- host12.test.com
- 把文字檔路徑指定到 HOSTFILE 環境變數
- export HOSTFILE=~/testarea/hostlist
- $ compgen -A hostname -- ho
撰寫產生 list 的 bash function
讓我們看一下最簡單的範例。補完指令 --help --verbose --version。
(範例來自 www.debian-administration.org)
_foo() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--help --verbose --version" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi } complete -F _foo foo
我們產生了 _foo() 含式,並且用 complete 這個指令告訴 bash, foo 這個指令可以用 _foo() 這個含式來產生自動補完清單。
讓我們看一下 _foo() 裡面有哪些是重要的變數。
- COMP_CWORD: 目前所在的 index
- COMP_WORDS: user 輸入的指令 array
- COMPREPLY: 產生出來的可用指令的 array。
剩下的,就是 bash 中複雜的 array 寫法了。
參考資料
- http://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2
沒有留言:
張貼留言