Search code examples
bashquoting

How to let empty arguments survive in command substitutions?


I want to call dialog à la:

dialog --menu Choose: 0 40 10 A '' B '' C ''

except A, B and C are the result of a dynamic query, for the sake of this question the latter being { echo A; echo B; echo C; }.

I can get the desired command line seemingly by:

{ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;"

but:

echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;")

and its output:

A '' B '' C ''

show that the result of the command substitution is only word-split, but '' isn't interpreted as an empty argument, but passed verbosely to echo (and thus, dialog wouldn't display no descriptions for the menu items, but literally ''s).

I can work around this in bash using arrays, but is there a simpler solution I'm missing?

Given

$ e() { printf "tag: [$1] item: [$2]"; }
$ e $(echo "A ''")
$ tag: [A] item: ['']

How can I change the $(...) part, such that the item is [] instead of [''].


Solution

  • You can change the IFS (internal field separator)

    $ IFS=, e $(echo "a,,")
    tag: [a] item: []
    

    Seems to work. Is it nice? I do not know but would give some array magic a try. By the way, you can often use ${parameter/pattern/string} for substitution instead of calling sed. Unfortunately it only operates on a variable, which makes it less usable.