0

I'm trying to implement bash completion for filenames where the list of names is retrieved by another program (e.g. pulled via the network). I've got it almost working, but the automatic escaping is causing me some problems. The code below is the simplest recreation of the issue I can muster:

#!/bin/bash

_myscript()
{
    local IFS=$'
'

    # Debugging:
    #echo
    #echo "./myscript $COMP_CWORD ${COMP_WORDS[@]}"

    COMPREPLY=( $(./myscript $COMP_CWORD ${COMP_WORDS[@]}) 
}

complete -o filenames -F _myscript myscript

Where the program that can actually retrieve the filenames is simulated by this script with the filename myscript:

#!/bin/bash

index=$(( $1 + 2 ))
cat matches.txt | fgrep "${!index}"

The matches.txt file referenced above is:

abc
def
ghi=jkl
mnl opq

So it properly tab completes everything if you only type the first few characters, producing the escaping that I would like:

./myscript 1 ./myscript gh<TAB>    ->    ... ghi\=jkl
./myscript 1 ./myscript mn<TAB>    ->    ... mnl\ opq

The issue is when tabbing after the equals or space, where it fails to complete:

./myscript 1 ./myscript ghi\=j<TAB>    (no change)
./myscript 1 ./myscript mnl\ o<TAB>    (no change)

Using the debugging it seems to be sending the following command to myscript (quotes added by me to indicate grouping only because it doesn't show up in the echo statement):

./myscript 1 ./myscript 'ghi\=j'
./myscript 1 ./myscript 'mnl\ o'

Which means my fgrep is searching for a filename that actually includes the escape character. It's taken a while to get to this point but the real question is this:

Why is it giving me an escaped version of the text I'm tab completing? When I eventually press the enter button, the escapes are going to be interpreted by bash and myscript won't receive them. So there seems to be a difference between what I'm receiving for tab completion and what I'm receiving when the user actually presses enter.

I don't really understand why $COMP_WORDS is being set with a version containing the escapes, when my understanding is that the array is what separates the arguments so it seems as though the escaping is unnecessary. Is there a useful function that safely removes these escapes or is my entire approach just wrong?

LVA
  • 1
  • see questions [#1](http://stackoverflow.com/questions/29728868/), [#2](http://stackoverflow.com/questions/26509260/), [#3](http://stackoverflow.com/questions/1146098/) – pynexj May 13 '17 at 15:37
  • `-o filenames` has side effects (*like adding a slash to directory names or suppressing trailing spaces*) so try if it works better without this option. – pynexj May 13 '17 at 15:41
  • The escaping provided by `-o filenames` is what I want. Thanks for the link to #3 though, in that question was the suggestion to use `eval echo $words` which does the job of unescaping before `COMPREPLY` passes the arguments to the external program. It seems to fix the above example which was already simplified, but I have a bit more work to figure out if it solves the more complicated completions that I'm trying to implement. – LVA May 14 '17 at 07:21

0 Answers0