![是否可以配置 bash 完成目錄名稱的方式?](https://rvso.com/image/1288703/%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E9%85%8D%E7%BD%AE%20bash%20%E5%AE%8C%E6%88%90%E7%9B%AE%E9%8C%84%E5%90%8D%E7%A8%B1%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%9F.png)
我想指示 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 刪除。如果有興趣,只需要求他取消刪除即可。