Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: get TAB completions as a list

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
like image 264
Peregring-lk Avatar asked Jul 09 '15 10:07

Peregring-lk


2 Answers

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.

like image 140
JB. Avatar answered Nov 13 '22 05:11

JB.


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

like image 2
betterworld Avatar answered Nov 13 '22 05:11

betterworld