How to allow empty arguments to 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, the last one for this question is { echo A; echo B; echo C; } { echo A; echo B; echo C; } { echo A; echo B; echo C; } .

I can get the desired command line, apparently:

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

a

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

and its conclusion:

 A '' B '' C '' 

show that the result of the command substitution is word-broken only, but '' not interpreted as an empty argument, but is passed verbatim to echo (and, therefore, the dialog will not display descriptions for menu items, but literally '' s).

I can get around this in bash using arrays, but is there a simpler solution that I am missing?

Considering

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

How can I change part of $(...) so that the element is [] instead of [''] .

+4
source share
3 answers

You can change IFS (internal field separator)

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

It seems to need work. It's cute? I do not know, but would give the magic of an array. By the way, you can often use ${parameter/pattern/string} for substitution instead of calling sed . Unfortunately, it only works with a variable, which makes it less useful.

+1
source

Good question.

I don’t know if this is β€œsimpler”, but it has a certain elegance:

 with-tags() { local line if read -r line; then with-tags " $@ " "$line" ""; else " $@ "; fi } { echo A; echo B; echo C; } | with-tags dialog --menu Choose: 0 40 10 

It is easily extensible to handle input lines of the TAG <optional description> form TAG <optional description> :

 with-tag-lines() { local tag desc if read -r tag desc; then with-tag-lines " $@ " "$tag" "$desc"; else " $@ "; fi } { echo A with optional description; echo B; echo C; } | with-tag-lines dialog --menu Choose: 0 40 10 
+2
source

You can try the following:

 cmd="dialog --menu Choose: 0 40 10 " arg="`echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;")`" eval "${cmd}${arg}" 

But I think sed is not required here. You can leave it simple:

 cmd="dialog --menu Choose: 0 40 10 " arg="`echo A \'\' B \'\' C \'\'`" eval "${cmd}${arg}" 
0
source

Source: https://habr.com/ru/post/1495221/


All Articles