I'm trying to create a dialog menu based on the results of the lsblk command. My goal is to read the first word as the menu item and the remaining words as the menu item description.
For example:
$ dialog --menu "Choose one:" 0 0 0 $(lsblk -lno name,size | grep sda)
This command works, because the dialog --menu option expects two arguments per menu item, in this case "name" and "size".
However, if I try the same command with a multi-word description (using the "read" built-in to write to stdout as two variables), word-splitting occurs in the second variable, even if quoted.
#commmand 1: unquoted variable
$ dialog --menu "Choose one:" 0 0 0 $(lsblk -lno name,type,size | grep sda |
> while read name desc; do
> echo $name $desc
> done) #results in output like below without quotes
#command 2: quoted variable
$ dialog --menu "Choose one:" 0 0 0 $(lsblk -lno name,type,size | grep sda |
> while read name desc; do
> echo $name "$desc"
> done) #results in output like below without quotes
#command 3: escape quoted variable
$ dialog --menu "Choose one:" 0 0 0 $(lsblk -lno name,type,size | grep sda |
> while read name desc; do
> echo $name \"$desc\"
> done) #results in output below
I don't understand why word splitting is occurring in the quoted variable. Can anyone explain and/or suggest a workaround? I've tried writing the output of lsblk to a file and reading the file with the same results. The desired output is:
EDIT: I looked at command quoting as a possible solution, but it results in the lsblk command output being passed to dialog as one argument when two are required.
Thanks.
while read -r name desc; do args+=($name "$desc"); done < <(lsblk -lno name,type,size | grep sda)
and thendialog --menu "Choose one:" 0 0 0 "${args[@]}"
– don_crissti Oct 18 '16 at 00:38zsh
(andgnu sed
) that doesn't usewhile ... read
:args=(${(f)"$(lsblk -lno name,type,size | sed -E '/sda/!d;s/ +/\n/')"})
then againdialog --menu "Choose one:" 0 0 0 "${args[@]}"
– don_crissti Oct 18 '16 at 18:30sh
(kinda ugly though...) - this one should be more portable:printf %s%s\\n 'dialog --menu "Choose one:" 0 0 0 '"$(lsblk -lno name,type,size | sed '/sda/!d;s/[[:blank:]]\{1,\}/&"/;s/$/"/' | tr '\n' ' ')" | sh
– don_crissti Oct 18 '16 at 18:32dialog --menu "Choose one:" 0 0 0 $(lsblk -lno name,type,size | sed '/sda/!d;s/[[:blank:]]\{1,\}/\n/;s/[[:blank:]]/_/g;s/\n/ /')
(this isgnu sed
syntax though, to make it work with othersed
s replace the 1st\n
with a backslash followed by a literal newline - I can't use that in a comment block as it won't be preserved...) – don_crissti Oct 19 '16 at 00:33