我经常遇到 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-/
而不是complete
(TAB
)。
答案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]”时,我没有得到这些名称,只有来自badblocks
to 的命令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 包。