What is the correct way to use the compgen -C
option?
I'm trying to learn about Bash programmable completion, and in particular the compgen
builtin function. I'm experimenting with the different compgen
command-line options, and I don't understand how the -C
flag is supposed to work. From the GNU Bash Reference Manual:
-C command
command is executed in a subshell environment, and its output is used as the possible completions.
Based on this, I expect something like the following to work:
$ compgen -C 'echo "first_option second_option"' f
first_option
But instead, I get this:
$ compgen -C 'echo "first_option second_option"' f
-bash: compgen: warning: -C option may not work as you expect
first_option second_option f
I've tried this with Bash version 4.2.45 on OS X 10.7 and with Bash version 4.2.25 on Ubuntu 12.04, and in both cases I get the same error:
-bash: compgen: warning: -C option may not work as you expect
Best Answer
Referring again to the bash manual page:
I assume this is the "unexpected behaviour" it's referring to. The lack of
$COMP_WORDS
and$COMP_CWORD
in the subshell created by compgen mean that your initial "f" doesn't get passed in to filter the results, hence the first two options you see. The third "f" -- I'll get on to.It's even more unexpected at first glance that there seems to be no way to suppress this output (apart from piping away stderr) - but in fact there's a reasonable explanation. The arguments are intended to be used against the
complete
command, with whichcompgen
shares code and arguments, and where they make more sense.The
complete
command is used in the registration of a completion command, e.g.complete -C /tmp/test.sh mycmd
And the bash source (in
pcompletion
,gen_command_matches()
or thereabouts) explains how your "f" got into the results:The third result in your example is of course your command input being passed back out as argument
$2
. Using the completion spec we created above, we can show more clearly how it's meant to be used with a script which annotates the arguments:then:
So it's not to say that
-C
can't be used by compgen; just that you're no better off than with$()
.I suppose the remaining question is, "why are -C and -F defined against compgen at all?". I don't know. Easier, maybe; or perhaps the authors decided a (rather obscure) warning was better than simply disabling what could be useful functionality. The answer, and probably the right thing to do at this point, is to make a bug report seeking clarification and/or improved documentation from the authors...