ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have several scripts that I am converting to dialog. Problem is that I am very new with dialog. I do have novice bash experience, and I have used zenity with some nautius scripts... I am major stumped with this dialog menu. This is just an test example of what I am trying to do. And I want one dialog menu to carry on to the next.
I am having a hard time with the last menu executing the specific command when selected from the list. I've tried while loops, 'if and else' Just stumped on how to store a "variable value" to use with my case statement.
Code:
#!/bin/bash
#USED TO TEST W/ Xdialog
DIALOG=${DIALOG=dialog}
$DIALOG --title "Proper tools needed for install" \
--yesno "Certain tools are required for installation \
NANO, GEDIT, TOP and WGET
Do you meet these requirments...?" 0 0
case $? in
0) clear;;
1) exit;;
255) exit;;
esac
#I HAVE TRIED A WHILE LOOP, IT ALWAYS RETURNS 0, I CAN NEVER EXECUTE
#ANY COMMANDS WITHIN THE LIST OTHER THEN 0
$DIALOG --clear --title "TOOLS" \
--menu "CHOOSE YOUR:" 20 51 4 \
"1" "NANO" \
"2" "GEDIT" \
"3" "TOP"
parti=$?
case $parti in
1) gparted;;
2) gedit;;
3) parted;;
255) exit;;
esac
This code is incomplete. I'm just really confused on how I can implement a loop into this, and execute the command selected in the menu, then resume into another dialog box. The man pages aren't clear on what I should do. And I have searched google hi & low for an example. So I'm hoping someone out there has some good advice, and maybe know of any good sites that references dialog's with loops that executes commands. Would be very helpful.
Need to know how to bind the menu items with commands listed.
EDIT: It seems that the only values available are "0 , 1 , 255" in a case statement. I need to figure out how I can store a value of the list to launch the program.
Last edited by manwithaplan; 03-07-2009 at 04:05 AM.
It seems my approach was all wrong. After further research I found that the output of the dialog results in a stderr. So I needed to save the output into a tempfile, then trap, and uses case statements within another too be able to have multiple choices, by reading the tempfile output. After reading the tempfile output it matches with the internal case statement and executes the command... Very long winded.
I guess I was to tired to figure this out when I first posted
Here is how to make (1 nano 2 gedit 3 top) from ([1]=nano gedit top):
Code:
CHOICES=([1]=nano gedit top)
declare -a CHOICES_ARGS # will be (1 nano 2 gedit 3 top)
{ # generate choices arguments to dialog
let j=0
for i in "${!CHOICES[@]}" ; do
args[$j]=$i
let j+=1
args[$j]="${CHOICES[i]}"
let j+=1
done
}
This way you can just change the CHOICES array when you want to add more tools.
Last edited by ntubski; 03-07-2009 at 08:16 PM.
Reason: added quotes
That won't work with 'dialog' as it uses stdout to present the dialog to the users screen. You can work around it with something like...
GazL, I figured that out yesterday when I was working with the /dev/null output. It wasnt working. Though I was able to get a variant to work with an input box, by outputing to tty.
GazL, your suggestion works perfectly for my menus... Thanks. Though could you explain to me these following commands? I'd rather learn to fish, then have someone fish for me.
"2>&1" Which I do know changes the stderr output...
"1>&3" Is this outputting to tty? and in the beginning you "exec 3>&1"
slightly confused on these suggestions.
thanks for all you input.
currently working on ntbuski's suggestions. New with working w/ array's, so I am looking to implement them into some of my code.
Are you suggesting declaring this array in the beginning of thee code?
Would love to know more about implementing this. I've been working off of online guides to learn... So forgive any ignorance.
That won't work with 'dialog' as it uses stdout to present the dialog to the users screen.
Ah, good point, I was thinking that dialog put up some graphical thing.
I believe you can put all the redirection in one command like this:
Code:
choice=$(dialog arguments... 3>&2 2>&1 1>&3)
Quote:
Originally Posted by manwithaplan
I'd rather learn to fish, then have someone fish for me.
When you run a command like var=$(cmd) by default you have stdout (aka &1) goes to var, and stderr (aka &2) goes to screen, (as opposed to just running cmd which is both stdout and stderr go to screen). Each of the redirection commands run in order like so:
Code:
| &1 (stdout) | &2 (stderr) | &3
-------+-------------+-------------+---------
| var | screen | closed
3>&2 | var | screen | screen
2>&1 | var | var | screen
1>&3 | screen | var | screen
you could even add this for symmetry
3>&- | screen | var | closed
Quote:
"1>&3" Is this outputting to tty? and in the beginning you "exec 3>&1"
slightly confused on these suggestions.
When you do exec redirection the redirection stays in effect for the rest of the script instead of just a single command.
So "exec 3>&1" means point fd3 to wherever stdout points to, at the time of that command stdout is pointing to the screen (aka tty). Then the "1>&3" means point stdout to wherever fd3 points to, which is the screen because of the previous command.
Quote:
Are you suggesting declaring this array in the beginning of thee code?
Would love to know more about implementing this. I've been working off of online guides to learn... So forgive any ignorance.
Yes. I'm happy to answer questions but "more about implementing this" is a bit vague...
Last edited by ntubski; 03-08-2009 at 06:50 PM.
Reason: quote attribution
Yes, 1>/dev/tty was the first thing I thought to try too. Interestingly, exec 3>/dev/tty also works just as exec 3>&1 did, however, using >/dev/tty directly inside the $() doesn't. I guess this is down to some internal nuance of how the shell handles command substitution, but I don't understand exactly what is going on here.
Quote:
Originally Posted by manwithaplan
GazL, your suggestion works perfectly for my menus... Thanks. Though could you explain to me these following commands? I'd rather learn to fish, then have someone fish for me.
I'm exactly the same in that regard. I didn't mean to leave you hanging, but sometimes its hard to guess how much someone knows on a topic, and if folks are really interested they'll ask follow-ups.
Anyway, I see ntubski has answered your queries already so no need to go over it again.
Not sure what you mean there, it seems to work for me, and I think manwithaplan was saying it worked for him.
Hmmm, yes it does for me today too, but didn't when I tried it yesterday. Maybe I'd managed to get the shell into a peculiar state or something. Oh well, not to worry.
Wow, a plethora of info. I'll post my example of trying to use dialog with a /dev/tty output.
Code:
ROOTS=$(dialog --backtitle "TEST - manwithaplan" --inputbox "Enter the device path for /ROOT \n\n\ Example: /dev/sdx" 12 40 2>&1 >/dev/tty)
The thing is I am unable to use a case statement following this command. Meaning the output is a string of text e.g. "(/dev/sdx)". I have no idea how to position an "if" or a "case" after to read the string of text, then interpret for results like: e.g. (mount, mkdir, etc...). I am still fairly new with programming.
I'm also working on using dialog's --gauge to show output of wget, & tar extractions. I've been working on a grep command to "grep" wget's log file too show a percentage. I've seen some "sed" example's ... but I am still working on the use of syntax and, feel overwhelmed with using sed. I'm currently working on several different things... just confused. Any idea's? I've been working with this example here, but it doesnt seem to display the progress bar.
And the earlier post when I asked about implemtation, I guess I didnt understand ntbuski's post on adding an "arg". Like I said still grasping syntax and commands. So I was more or less asking for an example code, of implementing into my original example with a dialog menu. That way I can visualize it and interpret. Putting ntbuski's examples together. Just have hard time visualizing your suggestion.
Thanks guys for your explanations and examples. Very helpful.
Actually I used a wildcard in a case statement. " /dev/*) " Seemed to work. I also put it in a while loop to return to the input box if the incorrect data was imputed. In case of user error or typo's.
GazL's e.g. was too limited. I just needed to experiment with using "*" wildcards in case statements to see if it would work... And to my surprise it worked.
Last edited by manwithaplan; 03-10-2009 at 02:23 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.