我想知道一种获取命令可能完成的列表但不执行它的方法。例如,要获取可以加载的 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)
一般来说,执行此操作的正常方法是compgen。但如果您使用标准的 bash 补全,则该modprobe案例将无法工作,因为它要经过 shell 函数调用。虽然这些受 的支持compgen,但文档和内联帮助善意地告知它可能不会执行您想要的操作。
$ complete -p modprobe\ncomplete -F _modprobe modprobe\n$ compgen -F _modprobe\nbash: compgen: warning: -F option may not work as you expect\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n\n分解:
\n\nbind \'set page-completions Off\'避免任何 \xe2\x80\x9c--More--\xe2\x80\x9d 提示,在不知道我们获得的页数的情况下很难编写脚本。
set completion-query-items 0避免 \xe2\x80\x9c显示所有 3598 种可能性?(y 或 n)\xe2\x80\x9d 提示。
sudo modprobe \\t\\t是不言自明的。不要忘记制表符之前的空格。
\\x15是 的十六进制C-u,默认绑定到unix-line-discard,以清除该行,以便sudo modprobe实际不运行。
请记住,此示例中的所有输出都将发送到 stderr。因此,如果您想提取它进行过滤,您将需要2> file,2>&1和 的某种组合|&。
两全其美的替代方案,自动化@betterworld 的M-*技巧:
\n\n$ echo -en \'sudo modprobe \\e*\\x01\\ed\\edecho\' | bash -i 2>/dev/null\nRun Code Online (Sandbox Code Playgroud)\n\n这强烈假设 emacs 编辑模式(默认)。set -o emacs\\n如果需要,请在前面添加 a 。