When creating shell completion functionality in bash, it seems like the -C
option would be powerful and common. It's defined like this:
-C command
command is executed in a subshell environment, and its output is used as the possible completions.
That seems really straightforward. But, weirdly, it's not. If I do:
$ complete -C "echo one two three" test.sh
and then type test.sh
and hit [tab] one time, I get that line filled out with
$ test.sh one two three test.sh test.sh
back. What?! For comparison,
$ complete -W "one two three" test.sh
does exactly what I'd expect: it offers one, three, or two as possible completions (in sort order, of course).
I can't find any good documentation anywhere, so I'm experimenting.... maybe a semicolon helps? complete -C "echo one two three;" test.sh
... Ah, okay, this helps some, because it removes that weird test.sh
from the end. But it still fills out the full string one two three
. This is odd, because that description above definitely says "possible completions", plural.
... so, hmmm, ah, newlines? Let's try complete -C "echo -e 'one\ntwo\nthree';" test.sh
.
Okay, so, this is promising. If I type test.sh [tab]
, I get back one three two
. But then, things go wrong. I add an o
to resolve the ambiguity, so, test.sh o[tab]
, and that returns
o one three two
Which is puzzling. In fact, any string I type gets added to the list; if I do test.sh wtf[tab]
, I get one three two wtf
echoed back. I guess possibly I need to do something sophisticated with compgen
, but, again, I stress, this works as expected with -W
. And, in fact
$ complete -W '$(echo one two three)' test.sh
works just fine (note single quotes to prevent premature expansion/execution, in case you do something more sophisticated than echo
which could produce variable results).
What am I missing here?