Search code examples
bashcommand-substitutionvariable-substitution

Bash: Insert variable content into command substitution as arguments - how to quote correctly?


I really really don't find a solution to this problem: Say I have a variable that has multiple lines, each line should be one argument in the end.

line   1
line two
...

I only get this data at runtime, but it should be build like this to an command:

answer="$(dialog --menu 'Menu title' 0 0 0 'line   1' - 'line two' - ... 3>&1 1>&2 2>&3)"

(Data has to be separated by an - but this is not a problem.)

I think I really tried every possible combination, but it won't work out. I checked this site already but I >think< it is not offering a solution to my problem: http://mywiki.wooledge.org/BashFAQ/050

Should I try to switch word splitting of?

This is my code as of now:

list=""
while read p; do
    list="$list '$p' - "
done <<< $line_separated_input

answer="$(dialog --menu 'Chosse sth' 0 0 0 $list 3>&1 1>&2 2>&3)"

Using an array also didn't work (As suggested here in (5): https://superuser.com/a/360986) :( How to stop word-splitting inside of quoted stuff, even if this quoted stuff is inserted because of variable substitution?

Edit: Thanks everybody, quoting $line_separated_input was part of the solution. Using it together with an array list instead of a variable finally solved my problem. You can check for yourself, having an additional command substitution makes things harder:

> list="'a  a'   'b    c'"; echo "$(echo $list)"
'a a' 'b c'
> list="'a  a'   'b    c'"; echo "$(echo "$list")"
'a  a'   'b    c'

Both have not the intended output. This is only achieved if I do the following:

> list=('a  a'   'b    c'); echo "$(echo "${list[@]}")"
a  a b    c

Tadaa! Thanks everybody :)


Solution

  • As gniourf_gniourf commented, you probably just need to double quote your variable like ... done <<< "$line_separated_input". An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators, thus it prevents word splitting, which can lead to unintended consequences.

    To better exemplify, see the following examples:

    var="/tmp/my directory"
    mkdir -p "$var"
    

    Output: the directory /tmp/my directory is created

    Now, without double quoting:

    var="/tmp/my directory"
    mkdir -p $var
    

    Output: the directory /tmp/my is created