如何建立具有自動完成功能的腳本?

如何建立具有自動完成功能的腳本?

當我使用類似程式時svn,我在 Gnome 終端中輸入:

svn upd

並點擊Tab它的自動完成:

svn update

是否可以在我的自訂 bash 腳本中執行類似的操作?

答案1

您必須建立一個新檔案:

/etc/bash_completion.d/foo

對於靜態自動完成(例如--help/ )新增以下內容:--verbose

_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
  • COMP_WORDS是一個包含目前命令列中所有單字的陣列。
  • COMP_CWORD是包含目前遊標位置的單字的索引。
  • COMPREPLY 是一個數組變量,Bash 從中讀取可能的補全。

compgen指令傳回 中的元素數組--help--verbose--version與目前單字相符"${cur}"

compgen -W "--help --verbose --version" -- "<userinput>"

來源

答案2

這是一個完整的教學。

讓我們來看一個admin.sh您希望自動完成功能被呼叫的腳本範例。

#!/bin/bash

while [ $# -gt 0 ]; do
  arg=$1
  case $arg in
    option_1)
     # do_option_1
    ;;
    option_2)
     # do_option_2
    ;;
    shortlist)
      echo option_1 option_2 shortlist
    ;;
    *)
     echo Wrong option
    ;;
  esac
  shift
done

注意該選項shortlist。使用此選項呼叫腳本將列印出該腳本的所有可能選項。

這裡有自動完成腳本:

_script()
{
  _script_commands=$(/path/to/your/script.sh shortlist)

  local cur
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  COMPREPLY=( $(compgen -W "${_script_commands}" -- ${cur}) )

  return 0
}
complete -o nospace -F _script ./admin.sh

請注意,要完成的最後一個參數是要新增自動完成功能的腳本的名稱。您需要做的就是將自動完成腳本新增到 bashrc 中,如下所示:

source /path/to/your/autocomplete.sh

或將其複製到:

/etc/bash_completion.d

答案3

您可以使用可程式完成。看/etc/bash_completion/etc/bash_completion.d/*的一些例子。

答案4

如果您想要的只是一個簡單的基於單字的自動完成(因此沒有子命令完成或任何其他內容),那麼該complete命令有一個-W選項可以做正確的事情。

例如,我有以下幾行來.bashrc自動完成一個名為朱皮特:

# gleaned from `jupyter --help`
_jupyter_options='console qtconsole notebook' # shortened for this answer
complete -W "${_jupyter_options}" 'jupyter'

現在jupyter <TAB> <TAB>為我自動完成。

文件gnu.org 上的內容很有幫助。

它似乎確實依賴IFS正確設定的變量,但這並沒有給我帶來任何問題。

若要新增檔案名稱完成和預設 BASH 完成,請使用以下-o選項:

complete -W "${_jupyter_options}" -o bashdefault -o default 'jupyter'

complete要在 zsh 中使用它,請在運行命令之前添加以下程式碼~/.zshrc

# make zsh emulate bash if necessary
if [[ -n "$ZSH_VERSION" ]]; then
    autoload bashcompinit
    bashcompinit
fi

相關內容