我有一个 bash 自动完成功能_customcomplete
,我想将其应用于名为 的脚本run.sh
。如果我调用complete -F _customcomplete ./run.sh
,那么只要我在同一个目录中并使用 调用它,自动完成脚本就可以正常工作./run.sh
。但是,如果我上一级并使用 调用它./scripts/run.sh
,自动完成脚本就不起作用。更重要的是,如果我在与另一个名为 的脚本不同的目录中run.sh
,自动完成脚本就会在该脚本上工作,而它不应该工作。
简而言之,是否可以将 bash 自动完成函数绑定到特定的可执行文件而不是调用字符串?
这是一个完整简化的示例:
这completion.sh
是一个非常简单的完成脚本,它总是返回三个选项one two three
::
_customcomplete() {
local word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "one two three" -- "$word") )
}
我可以使用以下资源source completion.sh
并可以验证它是否来源于type _customcomplete
:
_customcomplete is a function
_customcomplete() {
local word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "one two three" -- "$word") )
}
在一个目录中,我有两个文件夹scripts
和other
,它们都包含一个名为的脚本run.sh
。每个都只回显命令行参数以及一条唯一的消息来区分两者。
现在让我们尝试将补全函数注册到 中,run.sh
方法scripts
是进入脚本目录并运行complete -F _customcomplete ./run.sh
。现在我可以调用./run.sh
并使用制表符补全来查看 的可能性one two three
。但是,如果我尝试从上面的目录中将其调用为./scripts/run.sh
,我会得到默认的文件系统制表符补全建议。此外,如果我cd
进入other
,自定义制表符补全也适用于该脚本。
仅当使用与调用字符串完全相同的全局路径时,将命令更改complete
为链接到任何类型的全局路径才允许自定义 Tab 键补全。我想要的是能够通过任何相对路径调用脚本,并让自定义 Tab 键补全按预期工作。
答案1
似乎您想为命令的特定实例创建补全,而不管它是如何调用的(通过绝对路径或相对路径),但不希望为其他可能共享相同名称但位于其他地方的实例创建补全。例如,您可能希望为位于 的脚本创建补全~/bin/example.sh
,但不希望为 创建补全/usr/bin/example.sh
。
根据Bash 参考手册:8.6 可编程完成,bashcomplete
没有内置您想要的功能。但是,在您的_customcomplete
函数中,您可以使用找到被调用脚本的位置readlink
,然后进行COMPREPLY
相应的自定义:
_customcomplete() {
local CMD_NAME=`readlink -f "$1"`
local word="${COMP_WORDS[COMP_CWORD]}"
if [[ $CMD_NAME == '/home/user/bin/example.sh' ]] ; then
COMPREPLY=( $(compgen -W "one two three" -- "$word") )
fi
} &&
complete -F _customcomplete example.sh