是否可以配置 bash 完成目錄名稱的方式?

是否可以配置 bash 完成目錄名稱的方式?

我想指示 bash 使用特殊方法對某些目錄名稱執行補全。例如,如果路徑以「$$」開頭,bash將呼叫我的程式來執行補全,否則正常執行補全。

這是可能嗎?你會如何實施它?

賞金: 我真的很感激這個問題的答案。目標是讓自動跳轉當使用者以特定前綴啟動命令時,完成所有命令的路徑。例如,從較遠的目錄複製檔案時,您可以鍵入:

cp $$patern + <Tab>

自動跳轉將完成

cp /home/user/CompliCatedDireCTOry/long/path/bla/bla

您只需新增要放置檔案的位置即可。當然,我可以使用 ott 的註釋將其添加到一些特定的命令中,但如果有人有更好的想法,我將非常感激。

答案1

您可以透過覆寫 TAB(^i) 的預設綁定來完成此操作。首先,您需要覆寫 TAB 綁定,然後需要建立一個呼叫命令的函數,最後需要取得該命令的輸出並更新包含目前命令列的變數。

此函數會取得目前命令列並將最後兩個字元變更為“huugs”。

function my_awesome_tab_completion_function () {
  set -- $READLINE_LINE
  command="$1"
  shift
  argument="$*"
  argument_length=$(echo -n $argument | wc -c)
  if echo $argument | grep '^$$' >/dev/null 2>&1; then
    new_argument=$(echo $argument | sed 's/..$/huugs/') # put your autojump here
  else
    new_argument=$(compgen -d $argument)
  fi
  new_argument_length=$(echo -n $new_argument | wc -c)
  READLINE_POINT=$(( $new_argument_length - $argument_length + $READLINE_POINT ))
  READLINE_LINE="$command $new_argument"
}

對於您的範例,您可能希望將 new_argument 行變更為如下所示:

  new_argument=$(autojump $argument)

現在覆蓋 ^i 綁定:

$ bind -x '"\C-i"':'my_awesome_tab_completion_function'

現在測試它是否有效:

$ cd /ro<TAB>
changes my command to:
$ cd /root

所以正常完成仍然有效,您可以透過執行 cd $$... 等來測試 $$ 部分

如果遇到問題,請開啟詳細模式:

$ set -x

它將列印出該函數正在執行的所有操作。

我使用 bash 4.2.8(1)-release(預設)在 Ubuntu 11 上對此進行了測試。

答案2

bash 完成例程可以編程為 shell 腳本。

下面是一個 shell 腳本的範例,它將在任何參數中替換$$[Tab]my replacement string,但僅適用於特定命令mycommand,並且僅當參數恰好是 "$$" 時:

_mycomplete()
{
        if [ ${COMP_WORDS[COMP_CWORD]} == \$\$ ]
        then
                COMPREPLY='my replacement string'
        fi
}
complete -o default -o bashdefault -F _mycomplete mycommand

您必須透過(或點命令)將腳本來源到 bashsource <file-name>才能開始工作,然後:

mycommand $$[Tab] -> mycommand my replacement string
mycommand $$$[Tab] -> mycommand $$$ (beep)
mycommand whatever[Tab] -> (will complete "whatever" in the normal bash manner)

要始終讓它為部分或所有用戶工作,請將其包含在其中之一中bash 設定檔例程

該命令的問題complete在於,它僅適用於指定為參數的一個或多個命令名稱。人們可以簡單地給它提供用戶可能使用的所有命令的列表,或者在絕望的情況下擴展/bin/* /usr/bin/* ~/bin/*

在 CentOS 5.5 上測試。

這個簡單的腳本是基於我在另一個答案中列出的來源 - 這個答案已被版主 studiohack 刪除。如果有興趣,只需要求他取消刪除即可。

相關內容