LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash Dialog (https://www.linuxquestions.org/questions/programming-9/bash-dialog-4175427628/)

joshp 09-17-2012 08:38 AM

Bash Dialog
 
Hello All,

Can someone please example the following to me:

Code:

#!/bin/bash

cmd=(dialog --clear --title "Exchange" --menu "Please select exchange" 20 51 4)
options=("CME" "Hello"
        "CBOE" "Hello")

cmd=(dialog --clear --title "Exchange" --menu "Please select exchange" 20 51 4)
options=("CME" "Hello"
        "CBOE" "Hello")

coices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)

echo $options


echo $options

I am getting lost at
Code:

coices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
Thanks!

Josh

tc_ 09-17-2012 10:00 AM

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
Code:

echo $choices
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
Code:

choices=$( ... )
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.

MensaWater 09-17-2012 10:01 AM

It appears that this is poorly typed to me.

First there is no need to repeat the two cmd= lines with options as they are the same.

Second I suspect coices was meant to say "choices".

Third I suspect the first "echo $options" was meant to be "echo $choices". The intent of the line you asked about then becomes obvious - it is to show what choice the user made from the menu.

gnashley 09-17-2012 11:40 AM

See the dialog option '--stdout'.

tc_ 09-18-2012 04:49 AM

Incorporating gnashley's suggestion, my code would look like:
Code:

#!/bin/bash
cmd="dialog --clear --stdout --title Title --menu Menu 20 51 4"
options=(CME "Hello"
        CBOE "Hello")

choices=$(${cmd} ${options[@]})

echo $choices

I thought, I'd spell this out. Sorry for the noise to all, who know the man command ;)

gnashley 09-18-2012 10:15 AM

This does what you want:
Code:

choices=$(dialog --clear --stdout --title Title --menu Menu 20 52 4 CMD "hello" CBOE "hello") ; echo $choices

joshp 09-18-2012 10:26 AM

Thank you all, this is the first time I have used dialog, so just trying to understand it.

Josh


All times are GMT -5. The time now is 08:55 PM.