更改 bash 中内置读取的制表符补全

Mus*_*ann 6 bash readline tab-completion bash-completion

当“read -e”在 bash 中处于活动状态时,当前的制表符完成似乎仅匹配文件名:

read -e
[[TabTab]]
abc.txt  bcd.txt  cde.txt  
Run Code Online (Sandbox Code Playgroud)

我希望完成是由我定义的一组字符串,而文件/目录/主机名完成等应在“read -e”期间停用。

在脚本之外

complete -W 'string1 string2 string3' -E
Run Code Online (Sandbox Code Playgroud)

效果很好,但在使用“read -e”时我无法在脚本内完成这种工作。

ric*_*ici 3

尽管这似乎是一个合理的要求,但我认为这是不可能的。

内置函数的现有实现在调用 readline 处理输入read之前将 readline 完成环境设置为相当基本的配置-e。

您可以在函数builtins/read.def中看到, 中的代码:它在调用 的持续时间内设置为。有几个完成覆盖,因此这不是 100% 明显地重置整个完成环境,但据我所知,这是用于根据命令实现可编程完成的函数。edit_linerl_attempted_completion_functionNULLreadlinereadlinecomplete

通过一些工作,您可能可以修改命令的定义,read以允许使用特定的完成功能来代替 readline 标准文件名完成功能或除了 readline 标准文件名完成功能之外。这需要对 bash 内部结构有一个重要的了解,但如果您想熟悉这些内部结构,这将是一个合理的项目。

作为一种更简单但效率较低的替代方案,您可以编写自己的小实用程序,它只接受一行键盘输入readline并将其回显到标准输出。然后调用read将其标准输入重定向到您的实用程序:

read -r < <(my_reader string1 string2 string3)
Run Code Online (Sandbox Code Playgroud)

(假设my_reader使用其命令行参数来构建库的潜在完成列表readline。您可能还希望该选项能够显示提示。)

readline 文档包含一个执行简单自定义完成的应用程序示例;一旦你从 K&R 函数原型语法翻译它,它可能很容易适应你的需求。


编辑:当我再次查看该示例后,我认为它有很多不必要的细节,因此我编写了以下示例,减少了不必要的细节。我可能会将它上传到 github,但现在它就在这里,尽管它有近 100 行:

read -r < <(my_reader string1 string2 string3)
Run Code Online (Sandbox Code Playgroud)