Bash:以列表形式获取 TAB 完成

Per*_*-lk 5 bash autocomplete

我想知道一种获取命令可能完成的列表但不执行它的方法。例如,要获取可以加载的 linux 模块列表,您可以执行以下操作:

$ sudo modprobe [TAB][TAB]
... list of completions
Run Code Online (Sandbox Code Playgroud)

但是,如果想要将该列表“保存”在文件中怎么办?我认为complete为此目的应该有任何命令选项:

$ complete <whanever option> modprobe > modprobe-completion-list.txt
Run Code Online (Sandbox Code Playgroud)

或者,对于部分完成:

$ complete <whanever options> "modprobe i2" > modules-prefix-i2-list.txt
Run Code Online (Sandbox Code Playgroud)

JB.*_*JB. 3

一般来说,执行此操作的正常方法是compgen。但如果您使用标准的 bash 补全,则该modprobe案例将无法工作,因为它要经过 shell 函数调用。虽然这些受 的支持compgen,但文档和内联帮助善意地告知它可能不会执行您想要的操作。

\n\n
$ complete -p modprobe\ncomplete -F _modprobe modprobe\n$ compgen -F _modprobe\nbash: compgen: warning: -F option may not work as you expect\n
Run Code Online (Sandbox Code Playgroud)\n\n

它已被记录在案,因此可能有充分的理由;这个原因恰好超出了我的范围。

\n\n

无论如何,获得结果的一个非常棘手的方法是编写 readline 脚本。我不会在生产过程中放置​​类似的东西,但它在终端中工作得很好,尽管我还没有在更孤立的上下文(cron、守护进程)中测试它,但它实际上也可能在那里工作。

\n\n
$ echo -en "bind \'set page-completions Off\'\n            bind \'set completion-query-items 0\'\n            sudo modprobe \\t\\t\\x15" | bash -i\n$ sudo modprobe \n3c574_cs                       msi-laptop\n3c589_cs                       msi-wmi\n3c59x                          msp3400\n3w-9xxx                        mspro_block\n  (...)\nms_block                       zr36067\nmsdos                          zr364xx\nmsi001                         zram\nmsi2500                        \n$ exit\n
Run Code Online (Sandbox Code Playgroud)\n\n

分解:

\n\n
    \n
  • bind \'set page-completions Off\'避免任何 \xe2\x80\x9c--More--\xe2\x80\x9d 提示,在不知道我们获得的页数的情况下很难编写脚本。

  • \n
  • set completion-query-items 0避免 \xe2\x80\x9c显示所有 3598 种可能性?(y 或 n)\xe2\x80\x9d 提示。

  • \n
  • sudo modprobe \\t\\t是不言自明的。不要忘记制表符之前的空格。

  • \n
  • \\x15是 的十六进制C-u,默认绑定到unix-line-discard,以清除该行,以便sudo modprobe实际不运行。

  • \n
\n\n

请记住,此示例中的所有输出都将发送到 stderr。因此,如果您想提取它进行过滤,您将需要2> file,2>&1和 的某种组合|&

\n\n

两全其美的替代方案,自动化@betterworld 的M-*技巧:

\n\n
$ echo -en \'sudo modprobe \\e*\\x01\\ed\\edecho\' | bash -i 2>/dev/null\n
Run Code Online (Sandbox Code Playgroud)\n\n

这强烈假设 emacs 编辑模式(默认)。set -o emacs\\n如果需要,请在前面添加 a 。

\n