1. 程式人生 > >bash的按TAB鍵自動補全(自動完成)的原理與擴充套件

bash的按TAB鍵自動補全(自動完成)的原理與擴充套件

最近在用原始碼安裝ceph,發現命令不能自動補全,然後找到了下面這篇文章,寫的很好~轉載一下~

原始碼安裝ceph命令沒法自動補全的解決方法:把ceph-deploy安裝的可以自動補全的系統裡/etc/bash_completion.d下ceph的檔案scp到原始碼安裝對應的位置,然後“. /etc/bash_completion”就可以了~(注意點 . 號)

下面是正片環節~

用過bash的人,可能都對TAB自動補全功能有印象吧,按一下“TAB“鍵就自動幫你把命令或者檔名補全,確實好用。

這個應該是bash解析使用者輸入的時候,加上這個自動補全的功能的。方便的地方是bash提供的內建命令complete允許你對這個功能進行自定義擴充套件。 比如

complete -F _my_host my_ssh  就會指定 my_ssh這個名字的自動完成由 _my_host 這個函式去處理

比如我在 .bashrc 後面加上下面這個程式碼之後
----------------------------------------------
_my_host() {
    local HOST cur

    COMPREPLY=()
    _get_comp_words_by_ref cur

    HOST="local test test2 devolop"

    COMPREPLY=( $( compgen -W "$HOST" -- "$cur" ) )

}
complete -F _my_host my_ssh
alias egenera_ssh=/home/widebright/桌面/my_ssh.pl
-----------------------------------------------
這樣設定之後,在終端再輸入自己的自定義命令my_ssh 然後按TAB鍵,就會自動出來自己預先定義的host主機名字了
---------------
[email protected]:~/桌面$ my_ssh 
local test test2 devolop
-------------------------

其中COMPREPLY 是Bash的內建變數,一個數組,返回結果到這裡去後,bash就是讀取這個變數作為自動完成的匹配組合的。

compgen -W "$HOST" -- "$cur" 命令根據當前的輸入"$cur" 返回$HOST中匹配的部分。compgen也是內建命令的。_get_comp_words_by_ref 是預定義函式,不過自己從COMP_WORDS 和COMP_CWORD兩個預定義變數中去讀取當前輸入資訊。COMP_WORDS表示當前命令輸入引數的單詞陣列,COMP_CWORD表示當前游標的 位置。參考一個例子

------------------------
_xm() 
{
    local cur prev opts base
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    #
    #  The basic options we'll complete.
    #
    opts="console create list"


    #
    #  Complete the arguments to some of the basic commands.
    #
    case "${prev}" in
    console)
        local running=$(for x in `xm list --long | grep \(name | grep -v Domain-0 | awk '{ print $2 }' | tr -d \)`; do echo ${x} ; done )
        COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )
            return 0
            ;;
        create)
        local names=$(for x in `ls -1 /etc/xen/*.cfg`; do echo ${x/\/etc\/xen\//} ; done )
        COMPREPLY=( $(compgen -W "${names}" -- ${cur}) )
            return 0
            ;;
        *)
        ;;
    esac

   COMPREPLY=($(compgen -W "${opts}" -- ${cur}))  
   return 0
}
complete -F _xm xm
------------------------------------

complete 命令的和預定義的詳細說明可以參考bash的文件。
啟動complete -p 可以檢視bash已經定義的命令的自動完成函式。

現 在有一個叫做“Bash Completion  http://bash-completion.alioth.debian.org/ “的包,已經定義了很多名字的自動完成的處理函數了。只要你 “. /etc/bash_completion” 一下這些就全部可以用了。不過這個應該不用自己作了,我轉了ubuntu,都自動配置好了吧。不如在這個/etc/bash_completion.d這 個目錄下就還有很多命令的例子,比如:

/etc/bash_completion.d/apache2ctl
------------------------------------------------------
# apache2ctl(1) completion
have apache2ctl && {
_apache2ctl() {
    local APWORDS cur

    COMPREPLY=()
    _get_comp_words_by_ref cur

    APWORDS=$(apache2ctl 2>&1 >/dev/null | awk 'NR<2 { print $3; exit }' | \
        tr "|" " ")

    COMPREPLY=( $( compgen -W "$APWORDS" -- "$cur" ) )
}
complete -F _apache2ctl apache2ctl
}

# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh
--------------------------------------------------- 一個比較ubuntu 14.04可用的例子 [email protected]:/opt/smsc# cat /etc/bash_completion.d/smsc_ctl  # smsc completion function_exists() { declare -F $1 > /dev/null return $? } _smsc_ctl_auto_complete() { local cur cmds COMPREPLY=() local cur prev cmds COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} cmds="compile status start stop restart clean" if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W "$cmds" -- "$cur" ) ) elif [ $COMP_CWORD -eq 2 ]; then smsc_ctl=${COMP_WORDS[0]} sam_files=`$smsc_ctl ls` case "$prev" in "start") COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) ) ;; "stop") COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) ) ;; *) COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) ) ;; esac fi } complete -r ./smsc_ctl complete -r smsc_ctl complete -F _smsc_ctl_auto_complete smsc_ctl ---------------------------
很多時候,自己往系統裡面加了一些命令或者程式之後,自己再定義一個“自動完成”的處理給他,會方便很多的吧。

參考文章

8.6 Programmable Completion

https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.htmlAn introduction to bash completion:

8.7 Programmable Completion Builtins

https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html#Programmable-Completion-Builtins

An introduction to bash completion: part 1   http://www.debian-administration.org/articles/316
http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2
More on Using the Bash Complete Command   http://www.linuxjournal.com/content/more-using-bash-complete-command