dialog - display dialog boxes from shell scripts.
'dialog' is a utility for building console-based 'front ends' in UNIX like operating systems.
In this brief tutorial I am mentioning the usage of few important basic controls available with this 'dialog' utility and later I have created a very simple front end application in UNIX bash scripting using dialog.
To install 'dialog' on your ubuntu:
$ apt-get install dialog
Box options available with dialog: (Do a 'man' of dialog to know the usage of each control box)
--calendar
--checklist
--dselect
--editbox
--form
--fselect
--gauge
--infobox
--inputbox
--inputmenu
--menu
--mixedform
--mixedgauge
--msgbox
--passwordbox
--passwordform
--pause
--progressbox
--radiolist
--tailbox
--tailboxbg
--textbox
--timebox
--yesno
Checklist box:
A checklist box allows you to present a set of choices to the user and the user can toggle each one on or off individually using the space bar.
A sample one:
$ dialog --checklist "Choose OS:" 15 40 5 \
1 Linux off \
2 Solaris on \
3 'HP UX' off \
4 AIX off
Radiolist box:
The 'radiolist' control box is same as 'checklist' box.
$ dialog --backtitle "OS infomration" \
--radiolist "Select OS:" 10 40 3 \
1 "Linux 7.2" off \
2 "Solaris 9" on \
3 "HPUX 11i" off
Inputbox:
The 'inputbox' allows the user to enter a string.
$ dialog --title "Inputbox - Example" \
--backtitle "unstableme.blogspot.com" \
--inputbox "Enter your favourite OS here" 8 50
Menu box:
$ dialog --title "A dialog Menu Example" \
--menu "Please choose an option:" 15 55 5 \
1 "Add a record to DB" \
2 "Delete a record from DB" \
3 "Exit from this menu"
$ dialog --title "Example Dialog message box" \
--msgbox "\n Installation Completed on host7" 6 50
A yesno box:
$ dialog --title "Confirmation" --yesno "Want to quit?" 6 20
Infobox:
$ dialog --infobox "Processing, please wait" 3 34 ; sleep 5
Textbox:
It is a simple file viewer
$ dialog --textbox ~/work/conf.txt 10 4
From the sample application I have created at the end of this post, you will easily learn how to program these dialog boxes i.e. how to capture what user has entered/pressed. The dialog program writes its output to the standard error by default. In most of the dialog controls we redirect the choice user has selected to a tempfile and then process return value of dialog and contents of the tempfile.
Gauge Box:
#!/bin/sh
#A gauge Box example with dialog
(
c=10
while [ $c -ne 110 ]
do
echo $c
echo "###"
echo "$c %"
echo "###"
((c+=10))
sleep 1
done
) |
dialog --title "A Test Gauge With dialog" --gauge "Please wait ...." 10 60 0
Calendar Box:
#!/bin/sh
dat=$(dialog --stdout --title "My Calendar" \
--calendar "Select a date:" 0 0 25 12 2009)
case $? in
0)
echo "You have entered: $dat" ;;
1)
echo "You have pressed Cancel" ;;
255)
echo "Box closed" ;;
esac
Time Box:
#!/bin/sh
tim=$(dialog --stdout --title "A TimeBox" \
--timebox "Set the time:" 0 0 10 13 59)
case $? in
0)
echo "You have set: $tim" ;;
1)
echo "You have pressed Cancel" ;;
255)
echo "Box closed" ;;
esac
A sample application:
Suppose:
$ cat /home/user9/work/conf.txt
port:3322
threads:2
logdir:/opt/user6/logs/
confdir:/opt/user6/etc/
The following bash script using dialog utility will facilitate a simple interface to view or edit the content of the above config file.
#!/bin/sh
#http://unstableme.blogspot.com/
#A sample application using UNIX/Linux dialog utility
#Auto-size with height and width = 0 of the dialog controls
file='/home/user9/work/conf.txt'
tempfile1=/tmp/dialog_1_$$
tempfile2=/tmp/dialog_2_$$
tempfile3=/tmp/dialog_3_$$
trap "rm -f $tempfile1 $tempfile2 $tempfile3" 0 1 2 5 15
_edit () {
items=$(awk -F\: '{print $1,$2}' $file)
dialog --title "A Sample Application" \
--menu "What you want to change :" 0 0 0 $items 2> $tempfile1
retval=$?
parameter=$(cat $tempfile1)
[ $retval -eq 0 ] && tochange=$parameter || return 1
val=$(awk -F\: -v x=$tochange '$1==x {print $2}' $file)
dialog --clear --title "Inputbox - Test" \
--inputbox "Enter new value($tochange)" 0 0 $val 2> $tempfile2
dialog --title "Confirmation" --yesno "Commit ?" 0 0
case $? in
0) newval=$(cat $tempfile2)
awk -v x=$tochange -v n=$newval '
BEGIN {FS=OFS=":"}$1==x {$2=n} {print}
' $file > $file.tmp
mv $file.tmp $file
;;
1|255) dialog --infobox "No Changes done" 0 0
sleep 2
;;
esac
dialog --textbox $file 0 0
}
_main () {
dialog --title "A sample application" \
--menu "Please choose an option:" 15 55 5 \
1 "View the config file" \
2 "Edit config file" \
3 "Exit from this menu" 2> $tempfile3
retv=$?
choice=$(cat $tempfile3)
[ $retv -eq 1 -o $retv -eq 255 ] && exit
case $choice in
1) dialog --textbox $file 0 0
_main
;;
2) _edit
_main ;;
3) exit ;;
esac
}
_main
Dialog utility home page
26 comments:
one of the great things about "dialog" is that there is also "xdialog".
xdialog works just like dialog except it uses X to create the same dialog boxes as dialog but in GUI form.
So, it is very easy to write a script that checks if X is running and then substitutes xdialog for dialog is it is true. Making your program both terminal and X compatible.
@MetalX100, ya that makes sense.
So we can have a function like this
-----------------
isRunning () {
local SERVICE=$1
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
return 0
else
return 1
fi
}
isRunning XY && DIALOG='Xdialog' || DIALOG='dialog'
-----------------
I am sure there must be better alternatives to the above check of 'X running status'; please suggest. Thanks for your comment.
There is probably better way then this (In fact I know I use to do it a different way, but I can't remember how I use to do it), but this is how I would do it.
--------------------------
#!/bin/bash
if [ -f /tmp/.X0-lock ]
then
Dialog=Xdialog
else
Dialog=dialog
fi
$Dialog --title "Example Dialog message box" \
--msgbox "\n Hello World!" 6 50
-------------------------------------
/tmp/.X0-lock is a file created by X and I believe it is removed when X is shutdown (Oh, it contains the PID for X if you ever want to kill X from a script).
I have not done a lot of testing on this method, but it should work.
About detecting if X is running, just check environment variable DISPLAY, ie. something like
DIALOG=dialog
test -n "$DISPLAY" && DIALOG=xdialog
This way it'll detect X correctly when connecting with ssh, and as a bonus it's trivial to disable xdialog (like for testing) with unset DISPLAY.
Another gauge demo:
---------------
#!/bin/bash
{ for I in 10 20 30 40 50 60 70 80 90 \
80 70 60 50 40 30 20 10 0; do
echo $I
sleep 1
done
echo; } | dialog --guage "A guage demo" 6 70 0
--------------
You should also check out zenity (GTK/GNOME):
http://library.gnome.org/users/zenity/stable/zenity-introduction.html.en
There are many dialog programs out there for Linux. Zenity is one of my favorites. It just has a nicer look then most the others. But, it's only for GUI I think, no terminal counter part like dialog.
could you please explain this line:
[ $retval -eq 0 ] && tochange=$parameter || return 1
@tushar,
The meaning of :
[ $retval -eq 0 ] && tochange=$parameter || return 1
If retval is 0 (retval=$?, i.e retval contains the exit status of the previous command) then set 'tochange' to the content of the $parameter variable and if not 0 then return 1.
Assuming you have asked me for && and || :
# If you write "test && command", the command will only be executed if the test succeeds.
# If you write "test || command", the command will only be executed if the test fails.
Thanks for asking the question.
What you rarely find is a demonstration of several input fields on one dialog page. This works using --form:
dialog --backtitle "Network Interface Setup" \
--title "Network Configuration" \
--form "\nPlease enter the network configuration for eth0:" 11 55 3 \
"IP Address:" 1 1 "..." 1 16 16 15 \
"Network Mask:" 2 1 "255.255.255.0" 2 16 16 15 \
2> /tmp/setup-eth0.out
FORM=$(cat /tmp/setup-eth0.out | xargs)
for LINE in $FORM
do
echo $LINE
done
@Linus, thanks a lot. Its useful.
I'm brand new to all this. I get how to create everything, but I can't find anywhere how to use the input data. Especially on the timebox. After they put in the time, then what? This may not be the place to ask but I can't find help anywhere else.
In the "time" example the time you enter is saved to a variable called $tim.
So, after you run dialog you can:
echo "$tim"
or save it to a file:
echo "$tim" > time.log
Thanks, your short tutorial has been very useful. I've managed to create a dialog menu to select which of my servers to backup - using rsync.
Does anyone know how I can also use dialog to display the progress of my rsync, I'd like it to show each files as it's being copied - just so there's something to watch on the screen :-)
Thanks, your short tutorial has been very useful. I've managed to create a dialog menu to select which of my servers to backup - using rsync.
Does anyone know how I can also use dialog to display the progress of my rsync, I'd like it to show each files as it's being copied - just so there's something to watch on the screen :-)
@MikeAtVillage: Check --gauge and --mixedgauge options (from man page or with Google). Here's a one-liner to get you started on experimenting:
(a=0; while [ $a -le 100 ]; do echo $a ; let a=a+10 ; sleep 1 ; done) | dialog --gauge foo 10 30
Understanding what happens inside parenthesis is not critical, you just want to replace it with something that outputs correct values for your purpose.
@Ari, thanks for the solution.
Also I was wondering if we can make use of 'rsync -av --progress' option as well.
Jadu Saikia said: "Also I was wondering if we can make use of 'rsync -av --progress' option as well."
Unless rsync does something unusual, it'd probably be something like
rsync -av --progress | XXX | dialog --gauge 'rsync progress' 7 30
Where XXX is whatever is needed to process rsync output into percentage numbers, one per line. If rsync shows updates on separate lines, then one or two cuts and trs would probably do the trick in the most simple and "bashy" way. If it gets more complex, you might want to consider using perl or awk for processing, or just (while read line ; do ... ; done) if you want to use more plain shell script.
Note: If rsync updates a single line on screen, then tr "\\r" "\\n" can be used to convert that into multiple lines for easier handling (replace carriage returns with regular newlines).
Thanks, I'll give it a try.
which rpm to dwnload for dialog nd xdialog to work ??
@Guess-who-am-I , you can find the details here : http://www.icewalkers.com/rpm/dialog/fedora-core-6/download/dialog-1694.html
Which OS you are using ?
Hi Guys!
I am very much strucked here, i am using dialog in linux which pop up all kind of boxes in CLI mode, where as i could not find anything in solaris which is equivalent to dialog except Zenity, but zenity seems to work in GUI mode, how do i make it work in Command mode, displaying the box in terminal itself not in the desktop, for instance if iam connecting the server through putty im not able to access GUI. Please help!
Thanks in advance
@Sureshkumarchandrasekar, thanks for the question. first of all, X server should be running on your UNIX(solaris) machine. Then you can have a X client (CygwinX or hummingbird exceed) installed on your local machine and you would need to export your DISPLAY variable (something like this : http://www.hungry.com/~jamie/xexport.html). Hope this helps.
How to use a Gauge Box in a sudo command? Example:
make a progressbar to command: "sudo apt-get update" ?
Hello! How do i use a Gauge box to a "sudo apt-get update" progress? Tanks
Can someone please provide an example of how to use --editbox in RHEL5? I'm trying to have a multi-line input for a system bulletin board.
Thanks!!!
Post a Comment