bep*_*ter 5 bash autocomplete compgen
有许多可用资源(1、2、3)解释了如何利用 bash 自动完成命令和参数的能力,但所有这些资源都需要向用户添加代码,~/.bash_profile
或者/etc/bash_completion.d/*
有没有办法使一个脚本及其可用的完成是独立的?作为一个粗略和不完整的例子:
~/bin/script-with-integrated-autocomplete.sh:
#!/usr/bin/env bash
function _completions {
complete ...
}
if [ "$1" == "completions" ]; then
_completions
exit 0
fi
# (Whatever the script really does goes here.)
# ...
# ...
Run Code Online (Sandbox Code Playgroud)
交易破坏者(在这个问题的上下文中)是上面的例子仍然需要你添加类似的东西~/bin/script-with-integrated-autocomplete.sh completions
来.profile
完成。
有没有办法让单个 bash 脚本(文件)声明自己的完成并让 bash在调用时识别它们(理想情况下没有额外的系统或环境设置)?
正如对您的问题的评论中所述,如果没有任何先前的配置并且不更改当前环境,Bash 无法完成命令的命令行。Bash 不会查看文件,也不会尝试解释它们,除非您显式执行或获取它们。
\n\n我对这个主题的理解是,这样的功能不太可能很快进入 Bash,因为兼容性和资源问题 \xe2\x80\x94 作为一个 shell,它应该可靠地运行在各种不同的系统上,多种用途,适应多种用户的喜好;并且只有一个人作为开发者和维护者1。
\n\n虽然 Bash 提供了实现自动完成的工具,但完成生成器似乎在设计上就被设计为外部设施。事实上,您所寻找的内容可以通过现有工具和少量工作轻松实现。
\n\n给定示例脚本foo
:
#!/bin/bash\n\n# Setting up completion for foo. Only if the script is sourced\nif [ "$0" != "$BASH_SOURCE" ]; then\n _foo() {\n local cur\n COMPREPLY=()\n cur="${COMP_WORDS[COMP_CWORD]}"\n COMPREPLY=( $(compgen -W \'bar baz\' -- "$cur") )\n return 0\n }\n complete -F "_foo" "foo"\n return\nfi\n\n# The body of foo -- what it does when executed\necho foo "$*"\n# ...\n
Run Code Online (Sandbox Code Playgroud)\n\n使用bash-completion,可以通过将符号链接添加到foo
存储动态加载的用户完成的目录来启用自包含自动完成:
ln -s /path/to/foo ~/.local/share/bash-completion/completions/\n
Run Code Online (Sandbox Code Playgroud)\n\n确切的路径可能会有所不同,您可以参考 bash-completion\'s FAQ 了解如何在您的系统上检查其值。
\n\n如果没有 bash-completion,一种方法可能是定义一个默认的完成函数,如果命令满足某些条件,则该函数将提供命令(对应的文件);在这里,我们使用关联数组作为白名单(以避免盲目获取系统上的每个命令)。必须将此代码添加到您的.bashrc
(或等效文件,即每次启动交互式 shell 时在当前环境中获取的文件):
_default_completion () {\n # Do nothing when completion is invoked for an empty command\n if [ "$1" = "" ]; then\n return 1\n fi\n # Get the command path, exit with failure if it can\'t be found\n cmd=$(type -p "$1") || return 1\n if [ "${_compwhitelist["${cmd##*/}"]}" = y ]; then\n # Source the file corresponding to the command; on success,\n # return 124 to trigger a new autocompletion attempt\n source "$cmd" && return 124\n fi\n}\ncomplete -D -F _default_completion -o bashdefault -o default\n\n# The list of commands with embedded completion\ndeclare -A _compwhitelist\n_compwhitelist[foo]=y\n
Run Code Online (Sandbox Code Playgroud)\n\n我知道,您要求一个不需要编辑配置文件的解决方案,但请注意,始终需要一定量的配置。其中很大一部分是由发行版/软件包维护者完成的,即使用户可能永远不会意识到这一点。
\n\n1 参考:Chet Ramey 网站上的Bash 主页以及相关 Bash FAQ中的“A1” 。
\n