Well, this is a rather weird example.
First of all, there is absolutely no need, to include the definition of cmd and options twice in this script. Likewise, echoing the $options variable twice is presumably also unwanted behaviour. It should rather be
Apart from that, the following things are imho also quite strange:
Code:
cmd=(dialog --clear --title "Exchange" --menu "Please select exchange" 20 51 4)
options=("CME" "Hello" "CBOE" "Hello")
These are actually arrays of strings.
In other words,
Code:
cmd[0] = dialog
cmd[1] =--clear
cmd[2] =--title
etcetera etcetera... This is OK for the choices, but I think it is weird to use an array for the command.
Now, the commands
Code:
${cmd[@]}
${options[@]}
simply give the concatenation of all array elements, see
http://tldp.org/LDP/abs/html/arrays.html for a more in-depth introduction.
The redirection 2>&1 takes place in the original example since dialog returns its choices in stderr, which has number 2.
Here is a modified version:
Code:
#!/bin/bash
cmd='dialog --clear --title Title --menu Menu 20 51 4'
options=(CME "Hello"
CBOE "Hello")
echo $cmd ${options[@]}
choices=$(${cmd} ${options[@]} 3>&1 1>&2 2>&3 3>&- )
echo $choices
which has fewer oddities imho. The command ${cmd} is just a plain string and no array. Therefore, we can call it simply by ${cmd}. The options are still inside an array, which we concatenate to the call to ${cmd} by ${options[@]}. Then the magic happens. The command
runs the command(s) "..." and puts the stdout into the variable ${choices}. So what is all that a>&b stuff at the end of the command? We want to swap stderr and stdout since dialog writes its results to stderr and the "$( ... )" reads stdout into the given variable $choices. To this end, we do the following:
1. The 3>&1 makes descriptor 3 hold the value of descriptor 1, which is stdout
2. The 1>&2 makes descriptor 1 hold the value of descriptor 2, which is stderr
3. The 2>&3 makes descriptor 2 hold the value of descriptor 3, which holds stdout after our first step.
4. Finally, we delete the descriptor 3... it was just a temporary descriptor to swap stdout and stderr
EDIT:
There remains one question: Why is such heavy redirection necessary?
Well, stdout of dialog is redirected to stderr, which is displayed and not recorded into the variable $choices. Therefore, the user can actually interact with the script. If one would only redirect stderr to stdout, the user would not see that much. Try it!
So, there is still one problem left, with the above solution. It currently does not work with menu titles like "Choose your destiny:". I hope that some string escaping guru will have a look and resolve the issue.
Finally, credit goes to:
http://tldp.org/LDP/abs/html/arrays.html for the arrays
and
http://www.problem-hilfe.de/linux/h/...Umlenkung.html (german)
http://www.cc-c.de/german/linux/linux-dialog.php (german, too)
for the dialog and redirection stuff.
Here is some more english documentation:
http://tldp.org/LDP/abs/html/commandsub.html for the $(...).
and
http://tldp.org/LDP/abs/html/io-redirection.html for the redirections.
Hope, this helps a bit.