詳解Linux Shell命令自動補全
阿新 • • 發佈:2019-01-02
在Linux命令列下,輸入字元後,按兩次Tab鍵,shell就會列出以這些字元打頭的所有可用命令。如果只有一個命令匹配到,按一次Tab鍵就自動將這個命令補全。比如,想更改密碼,但只記得這個命令前幾個字母是pass。這時候,按Tab鍵,shell就自動輸出 passwd 命令,非常方便。
如下,測試foo命令是否自動補全
(如果只在當前帳號生效,只要配置 ~/.bashrc 即可)在bashrc檔案末尾加上 source /etc/bash_completion.d/foo.bash,這樣,每次登入到linux後,就會啟用這個補全指令碼。
演示下:
例如,設定命令補全後不要多加空格,方法如下:compopt -o nospace
help 只是演示,沒有特殊作用現在跑下這個例子:
參考:http://blog.csdn.net/mycwq/article/details/52420330
https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.htmlhttp://kodango.com/bash-competion-programminghttp://unix.stackexchange.com/questions/55520/create-bash-completion-script-to-autocomplete-paths-after-is-equal-signhttps://devmanual.gentoo.org/tasks-reference/completion/index.html
當然,除了命令補全,還有路徑、檔名補全。這個在我們 cd 到特定目錄時特別好用。
命令補全效果,如下:
那麼,自己開發的程式,該怎麼實現Tab自動補全?
補全命令說明
自動補全是Bash自帶的一個強大的功能,允許通過編碼指定命令引數如何補全。通常,補全指令碼會放在/etc/bash_completion.d/ 目錄下,方便統一啟用所有補全指令碼。這裡例子的命令為 foo# cat /etc/bash_completion.d/foo.bash _foo() { local cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $(compgen -W "exec help test" -- $cur) ) } complete -F _foo foo
如下,測試foo命令是否自動補全
# chmod +x /etc/bash_completion.d/foo.bash
# source /etc/bash_completion.d/foo.bash
# foo [Tab][Tab]
exec help test
以上,source是為了這個foo.bash在當前會話生效。預設情況下,這個補全指令碼不會被執行到,也就是說,補全命令未啟用。需要source啟用這個指令碼,就可以沒有顧慮地使用了。為了避免每次都要source一次,可以在bashrc加上這個命令。bashrc全域性配置在不同 linux 發行版可能位置不同,如下:Centos | /etc/bashrc |
Ubuntu | /etc/bash.bashrc |
補全命令詳解
前面給大家演示的例子,用到兩個命令complete和compgen,下面分別介紹這兩個命令。complete (補全命令)
這是命令補全最核心的命令了,來看下這個命令的引數說明。重點說明:# help complete complete: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
-F function | 執行shell 函式,函式中生成COMPREPLY作為候選的補全結果 |
-C command | 將 command 命令的執行結果作為候選的補全 結果 |
-G pattern | 將匹配 pattern的檔名作為候選的補全結果 |
-W wordlist | 分割 wordlist 中的單詞,作為候選的補全結果 |
-p [name] | 列出當前所有的補全命令 |
-r [name] | 刪除某個補全命令 |
# complete -W 'word1 word2 word3 test' foo
# foo w<Tab>
# foo word<Tab>
# complete -p
complete -W 'word1 word2 word3 test' foo
complete -o filenames -F __udisks udisks
# complete -r foo
# complete -p
complete -o filenames -F __udisks udisks
compgen(篩選命令)
這個命令,用來篩選生成 匹配單詞的 候選補全結果# help compgen
compgen: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
重點說明:-W wordlist | 分割 wordlist 中的單詞,生成候選補全列表 |
# compgen -W 'word1 word2 test'
word1
word2
test
# compgen -W 'word1 word2 test' word
word1
word2
compopt(修改補全命令設定)
這個命令可以修改補全命令設定,注意了,這個命令必須在補全函式中使用,否則會報錯。# help compopt
compopt: compopt [-o|+o option] [-DE] [name ...]
重點說明:+o option | 啟用 option 配置 |
-o option | 棄用 option 配置 |
內建補全變數
除了上面三個命令外,Bash還有幾個內建變數來輔助補全功能,如下:COMP_WORDS | 型別為陣列,存放當前命令列中輸入的所有單詞 |
COMP_CWORD | 型別為整數,當前輸入的單詞在COMP_WORDS中的索引 |
COMPREPLY | 型別為陣列,候選的補全結果 |
COMP_WORDBREAKS | 型別為字串,表示單詞之間的分隔符 |
COMP_LINE | 型別為字串,表示當前的命令列輸入字元 |
COMP_POINT | 型別為整數,表示游標在當前命令列的哪個位置 |
命令列補全例項
下面再結合前面三個補全命令(complete/compgen/compopt)和內建變數,寫了例子說明下。# cat /etc/bash_completion.d/foo.bash
_foo()
{
COMPREPLY=()
local cur=${COMP_WORDS[COMP_CWORD]};
local cmd=${COMP_WORDS[COMP_CWORD-1]};
case $cmd in
'foo')
COMPREPLY=( $(compgen -W 'help test read' -- $cur) ) ;;
'test')
local pro=( $(awk '{print $1}' /data/a.txt) )
COMPREPLY=( $(compgen -W '${pro[@]}' -- $cur) ) ;;
'*')
;;
esac
if [[ "${COMP_WORDS[1]}" == "read" && ${COMP_CWORD} -eq 2 ]]; then
local pro=($(pwd))
cd /data
compopt -o nospace
COMPREPLY=($(compgen -d -f -- $cur))
cd $pro
fi
return 0
}
complete -F _foo foo
例子中, foo有3個引數,分別是 help, read, testread 測試遍歷 /data 目錄下所有檔案test 測試從檔案中提取2級引數help 只是演示,沒有特殊作用現在跑下這個例子:
# mkdir /data
# touch /data/a.txt
# touch /data/b.txt
# tree /data
/data
├── a.txt
└── b.txt
0 directories, 2 files
# source /etc/bash_completion.d/foo.bash
# foo [Tab][Tab]
help read test
# echo world1 >> /data/a.txt
# echo world2 >> /data/a.txt
# foo test world[Tab][Tab]
world1 world2
# foo read[Tab][Tab]
a.txt b.txt
參考:http://blog.csdn.net/mycwq/article/details/52420330
https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.htmlhttp://kodango.com/bash-competion-programminghttp://unix.stackexchange.com/questions/55520/create-bash-completion-script-to-autocomplete-paths-after-is-equal-signhttps://devmanual.gentoo.org/tasks-reference/completion/index.html