[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: ssh config "Include" and bash completion

>     local included=$( command sed -ne
> 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\{1,\}\([^#%]*\)\(#.*\)\{0,1\}$/\1/p'
> "${configfile}" )

So, "included" is a string variable containing the ouput of sed.

If I'm reading that regex correctly, there'll be one pathname per line.

>     for i in ${included[@]}; do

But then the function attempts to treat the string variable as an array,
and then attempts to iterate over the "array" using an unquoted expansion.

Code like this is one reason why I do not use bash-completion.  Any time
it doesn't fail is just a lucky coincidence.

In this particular instance, it "works" so long as each pathname in
sed's output contains NO whitespace and NO globbing characters.  The
array syntax is a total red herring, though -- you get the same result
(success or failure) just by expanding the string variable with regular
string expansion syntax.

wooledg:~$ included=$'/foo/bar\n/Program Files/junk'
wooledg:~$ args ${included[@]}
3 args: </foo/bar> </Program> <Files/junk>
wooledg:~$ args $included
3 args: </foo/bar> </Program> <Files/junk>

A correct implementation would have "included" be a real array variable,
initialized by splitting the sed output on newlines, so that each
pathname becomes one array element.  Then, a *correct* array expansion
(with double quotes) would work:

wooledg:~$ included=(/foo/bar "/Program Files/junk")
wooledg:~$ args "${included[@]}"
2 args: </foo/bar> </Program Files/junk>

I don't know whether bash-completion is targeting bash 4.x exclusively,
or older bash versions.  If it's targeting bash 4.x then it could use
mapfile to initialize the array from sed's output.  Otherwise, it needs
a loop.

Reply to: