是否可以为碰巧共享相同名称的单独命令使用单独的 bash 完成函数?

Is it possible to have separate bash completion functions for separate commands which happen to share the same name?

我有两个独立的脚本,它们具有相同的文件名,在不同的路径中,用于不同的项目: /home/me/projects/alpha/bin/hithere/home/me/projects/beta/bin/hithere.

相应地,我有两个单独的 bash 完成脚本,因为每个脚本的正确完成都不同。在完成脚本中,"complete" 命令是 运行 每个完成指定有问题的脚本的全名,即

complete -F _alpha_hithere_completion /home/me/projects/alpha/bin/hithere

然而,只有最近的 运行 脚本似乎有效果,不管 hithere 的哪个实际版本被调用:似乎 bash 完成只关心关于命令的文件名并忽略路径信息。

有什么方法可以改变这种行为,以便我可以让这两个独立的脚本具有相同的名称,每个脚本具有不同的完成功能?

请注意,我对需要 alpha 了解 beta 的解决方案不感兴趣,或者需要第三方组件了解其中任何一个的解决方案——这会破坏我的目的。

Bash manual 描述了补全的查找过程:

If the command word is a full pathname, a compspec for the full pathname is searched for first. If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash. If those searches do not result in a compspec, any compspec defined with the -D option to complete is used as the default.

所以 complete 使用的完整路径,但前提是您通过其完整路径调用命令。至于仅使用短名称来完成工作,我认为您唯一的选择(从规范来看)将是某种动态挂钩,它根据 $PWD 确定调用哪个完成函数 - 我不没有看到任何证据表明 Bash 支持像您想象的那样重载完成名称。

是的,这是可能的。但这有点棘手。我将它用于我正在开发的未来脚本概念:所有脚本都具有与构建脚本相同的名称,但仍然 bash 完成可以完成它的工作。

为此,我使用了两个步骤:首先,我在 ~/.config/bash_completion.d 中放置了一个主脚本。此脚本旨在覆盖特定共享脚本名称的所有脚本。我配置了 ~/.bashrc 以便为这些脚本加载 bash 完成文件。

脚本将获取我想要 bash 完成的特定脚本文件的完整文件路径。从这条路径我生成一个标识符。对于此标识符,存在一个提供实际 bash 完成数据的文件。因此,如果执行 bash 完成,主 bash 完成脚本中的 bash 完成功能将检查该文件并加载其内容。然后它将继续常规 bash 完成操作。

如果您有两个同名的脚本,您将有两个不同的标识符,因为这些脚本共享相同的名称但具有不同的路径。因此,可以使用两种不同的 bash 完成配置。

这个概念很有魅力。


注意:我会尽快更新此答案并提供一些源代码。