我想指示 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 删除的来源。如果感兴趣,请让他恢复删除。