I would like to know a way to get a list of possible completions of a command but without executing it. For example, to get a list of linux modules which can be load, you could do:
$ sudo modprobe [TAB][TAB]
... list of completions
But, what if a want to "save" that list in a file? I think there should be any option of complete
command for that purpose:
$ complete <whanever option> modprobe > modprobe-completion-list.txt
or, for partial completions:
$ complete <whanever options> "modprobe i2" > modules-prefix-i2-list.txt
The normal way to do this in general would be compgen
. But if you're using the standard bash-completions, the modprobe
case won't work, since it goes through a shell function call. While those are supported by compgen
, the documentation and inline help kindly inform it probably won't do what you want.
$ complete -p modprobe
complete -F _modprobe modprobe
$ compgen -F _modprobe
bash: compgen: warning: -F option may not work as you expect
It's documented, so it's probably for a good reason; that reason just happens to be beyond me.
A very hacky kludge to get your results anyway is to script readline. I wouldn't put something like that in a production process, but it works fine in the terminal, and though I haven't tested it in more isolated contexts (cron, daemons), it might actually work there too.
$ echo -en "bind 'set page-completions Off'
bind 'set completion-query-items 0'
sudo modprobe \t\t\x15" | bash -i
$ sudo modprobe
3c574_cs msi-laptop
3c589_cs msi-wmi
3c59x msp3400
3w-9xxx mspro_block
(...)
ms_block zr36067
msdos zr364xx
msi001 zram
msi2500
$ exit
Decomposed:
bind 'set page-completions Off'
avoids any “--More--” prompting that would be uneasy to script through without knowing the number of pages we're getting.
set completion-query-items 0
avoids the “Display all 3598 possibilities? (y or n)” prompting.
sudo modprobe \t\t
is pretty self-explanatory. Don't forget the space before the tabs.
\x15
is hex for C-u, bound by default to unix-line-discard
, to clear the line so the sudo modprobe
isn't actually run.
Keep in mind just about all the output in this example goes to stderr. So if you want to extract it for filtering, you'll need some combination of 2> file
, 2>&1
and |&
.
Alternative best of both worlds, automating @betterworld's M-* trick:
$ echo -en 'sudo modprobe \e*\x01\ed\edecho' | bash -i 2>/dev/null
This strongly assumes emacs editing mode (the default). Prepend a set -o emacs\n
if you need to.
Type sudo modprobe <Esc>*
, this should insert all completions into your command line. Then edit the line so that it becomes echo [list of modules] > file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With