为什么 bash 禁用某些命令的自动完成功能以及如何启用它?

为什么 bash 禁用某些命令的自动完成功能以及如何启用它?

我经常遇到 bash 禁用某些命令的自动完成功能。这迫使我向命令名称添加随机符号,使用自动完成功能,然后修复命令名称。这很烦人。例如:

# I type:
openvpn s<tab>
# Nothing happens, so I add x
openvpnx s<tab>
# Now this expands to
openvpnx somepath

# Same with ./configure or many other commands...

有没有办法禁用禁用功能,以便自动完成始终有效?

答案1

上市完成情况

您可以使用 来查看 Bash/Readline 用于完成命令的内容complete -p command,例如,如果我运行complete -p openvpn,我会得到

bash: complete: openvpn: no completion specification

这表明我的 shell 使用的 Readline 没有任何特定的命令完成,openvpn因此它默认为传统的完成形式,即文件名。

另一个例子(演示定义的完成):

$ complete -p dillo
complete -F _filedir_xspec dillo

这表明名为的函数_filedir_xspec用于提供dillo命令的补全。

删除已完成的内容

要删除定义的完成,请使用-r带有complete内置选项的选项:

complete -r openvpn

答案2

bash 有可编程完成。自 1999 年以来,它已经能够适应命令参数的完成,而不仅仅是完成文件名。当未配置特定于命令的完成时,文件名是默认值(这就是当您将命令更改为 时您会获取文件名的原因openvpnx)。

可编程完成通常通过加载来激活/etc/bash_completion。如果您根本不需要可编程完成,并且始终希望完成文件名,即使在文件名没有意义的上下文中,请将其从您的.bashrc.

看来您对openvpn命令的参数有自定义完成,并且此完成代码不为第一个参数提供任何内容。我不知道为什么会这样,这可能是完成代码中的错误。有用的完成代码可以完成选项及其参数。运行complete -p openvpn以查看调用哪些代码来完成 的参数openvpn。您可以使用 禁用此自定义完成代码complete -r openvpn,但随后您将仅返回到文件名,这openvpn仅在几个选项之后的命令行中才有用。

无论完成设置如何,您始终可以通过调用来完成文件名complete-filename(默认绑定:)M-/而不是completeTAB)。

答案3

第一个问题是openvpn二进制文件名称与 init.d 目录中的条目相匹配。

complete | grep -i openvpn

产量

complete -F _service /etc/init.d/openvpn

在 Ubuntu 及其衍生版本上,这来自/usr/share/bash-completion/bash_completion(包的一部分bash-completion)中的代码。

for svcdir in ${sysvdirs[@]}; do
    for svc in $svcdir/!($_backup_glob); do
        [[ -x $svc ]] && complete -F _service $svc
    done
done

注释掉这个块。重新启动 bash 实例。尝试openvpn使用 TAB 进行自动完成并执行

complete | grep -i openvpn

这产生了

complete -F _openvpn /etc/init.d/openvpn

第二个问题来自/usr/share/bash-completion/completions/openvpn。它会尝试自动完成 /etc/openvpn 中的 .conf 文件,如果您尝试使用位于 /etc/openvpn 之外的某些临时配置文件运行 openvpn,它会成为一个障碍。

只需删除它并重新启动 bash 实例即可。

sudo rm /usr/share/bash-completion/completions/openvpn

现在您应该使用 TAB 键获得 openvpn 命令的标准文件补全。

如果你跑

complete -p | grep openvpn

在您尝试在 openvpn 之后自动完成之后,您现在应该得到

complete -F _minimal openvpn`

更好的方法是修复/扩展 openvpn 的 bash 完成脚本。但这是另一天的故事。


如果您稍后想恢复到bash-completion软件包的原始状态,只需使用以下命令重新安装它即可。

apt-get install --reinstall bash-completion

答案4

我的答案的悲伤部分是:bash(通过readline)有很多完成的可能性。但是普通的 Linux 发行版可以通过添加 [tab](或 [tab][tab])来干扰基本文件名扩展选项扩展。就我而言,它是软件包“bash-completion”这给了我原始问题中描述的行为。

这不仅仅是一个openvpn问题。 Q 说:“例如”。

bind -p | grep complete得到:

"\C-i": complete
"\e\e": complete
"\e!": complete-command
"\e/": complete-filename
...
"\e\C-i": dynamic-complete-history
"\eg": glob-complete-word
"\e*": insert-completions
# menu-complete (not bound)
...
"\C-x/": possible-filename-completions

这是哪里TAB = ctrl-i与基本功能绑定complete。我刚刚尝试了 archlinux 上的其他绑定。使用“ta[esc][star]”,我可以获取在命令行中插入的所有以“ta”开头的命令。

readline函数complete在 man bash 中解释:

正在完成

完整(选项卡)

尝试对点之前的文本执行补全。 Bash 尝试将文本视为完成多变的 (如果文本以 $ 开头),用户名(如果文本以 ~ 开头)、主机名(如果文本以 @ 开头),或命令(包括别名和函数)依次。如果这些都没有产生匹配,文件名 尝试完成。

我只能部分重现这一点。我认为 man bash 忘记提及这取决于您是否 [tab] 第一个单词或第二个、第三个等单词。

我的家庭/工作目录中有以“ba”开头的文件。当我在提示符下输入“ba[tab]”时,我没有得到这些名称,只有来自badblocksto 的命令bashbug。这是一个明智的行为:第一个单词为您提供命令,后面的单词为文件名。如果您输入“$[tab]”,您确实会得到一个很好的变量名称列表。

实际上,当我说 [tab] 时,我的意思是 [tab][tab]。但我们已经习惯了这一点,以至于我们甚至没有注意到这个“完整”的 readline 函数的作用。通过“完整”变体,您可以控制搜索内容(命令、文件名、变量)以及在存在多个匹配项(可能性)时如何处理列表。

这些 readline 函数带有许多默认绑定。man bash和都man readline列出了函数及其默认绑定。要检查,请使用上面的 bind -p 。这也是该文件的基础~/.inputrc。我刚刚做了一个(只有一个神秘的 /etc/inputrc):

set colored-completion-prefix on
set colored-stats on

通过 color-stats 我得到一个彩色列表,就像ls --color.在“bi[tab][tab]”之后,我看到“bind”为白色,“bison”为绿色,告诉我“bind”不是可执行文件(而是内置的......这是命令扩展...... “bind”甚至不是文件名!)。

set show-all-if-ambiguous on

此控制选项卡与双选项卡。添加并输入后

cd s[tab]

我直接得到所有文件名的彩色列表。目录、链接、普通文件等都以自己的颜色显示。

这些读取行变量你可以看到与bind -v.要测试 .inputrc 更改,请使用“bash”启动新的 bash,然后退出。或者重新登录。

下一层是在/usr/share/bash-completion

它包含每个命令的脚本,大部分来自 util-linux 和 systemd 软件包。有一个 mount (2 Kb) 和一个 systemctl (13 Kb) 文件。挂载文件很有趣:在您输入“-t”后,它会为您提供/proc/filesystems。

通常在“mount -t [tab]”之后我会得到文件名。在获取“挂载”文件后,我确实获得了 ext2、ext3 和 ext4 等文件系统类型。我去:

complete -r mount

删除此功能。 (这complete是一个 shell 内置命令)

第三层是额外的“bash-completion”包。我安装测试后已经卸载了它。通过这个包,我获得了扩展选项和包名称的好功能。我可以输入“tar --[tab]”,然后我会看到所有选项。但文件名扩展在许多星座中都丢失了。 AMD 不仅仅在 archlinux 上。

这个bash-completion包给了我一个2000行的脚本“bash_completion”和很多命令文件。 “tar”的代码有 700 行,功能齐全。所以解决这个问题并不是解决办法。

如果您真的关心这些 [tab] 完整的微妙之处,则必须从底部开始并选择一两个 readline 功能,而不是complete绑定到 [tab] 之外的其他键。我上面的默认配置确实有效,但我除了[tab]之外从未使用过任何东西。现在我想为正确的键设置正确的功能。带或不带选项扩展 bash-completion 包。

相关内容