dialog boxes in bash scripts

This library include simple functions to create ncurses, GTK or QT dialog boxes in bash scripts, depending on environment or user preferences. It uses kdialog, zenity and dialog, providing dialog boxes in the same script a different style whether it is executed in KDE, Gnome or console. The default is kdialog for KDE, zenity for other X sessions and dialog for the console (you might have to install this little old program with: zypper in dialog)

#! /bin/bash
#: Title       : popup
#: Date Created: Tue Jan 18 03:04:36 PST 2011 
#: Last Edit   : Tue Jan 18 23:20:05 PST 2011 
#: Author      : please_try_again 
#: Version     : 1.0
#: Description : a simple set of ncurses/QT/GTK dialog box functions
#:             : usable in other scripts
#: usage       : source /usr/local/bin/popup
#:             : type pophelp for a full description
#
#: Copy and paste this text into a text file and save it in /usr/local/bin as the file popup.
#: Import in other scripts or on the command line with: source /usr/local/bin/popup 
#: 
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# You might customize the functions by changing the variables below

# Uncomment to enforce the use of zenity dialogs in KDE
#ZENITY=1

# set default editor. If unset $EDITOR will be used.
# if EDITOR is not set, vi will be used :-)
#edit=nano

# uncomment one of the 3 lines below to enforce the use of text, 
# kdialog or zenity dialogs
#dflag=0	# dialog 
#dflag=1  	# kdialog
#dflag=2  	# zenity
#
# options for console dialog
DIALOGOPTS="--colors --shadow"

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

prg=$(basename $0)

function pophelp {
cat << EOFHELP
`tput bold`
NAME
`tput sgr0`	$prg - create ncurses, QT or GTK dialog boxes. 

`tput bold`SYNOPSIS
	ask `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`entry `tput sgr0;tput setaf 7`"prompt:text"`tput sgr0`
	`tput bold`warn  `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`notice `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`error `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`fileopen `tput sgr0;tput setaf 7`<directory>`tput sgr0`
	`tput bold`fileshow `tput sgr0;tput setaf 7`<file>`tput sgr0`
	`tput bold`fileedit `tput sgr0;tput setaf 7`<file>`tput sgr0`
	`tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...`tput sgr0`
	`tput bold`pophelp `tput sgr0;` show this help.

`tput bold`DESCRIPTION`tput sgr0`
`tput bold`popup`tput sgr0` uses the programs dialog, kdialog or zenity to create ncurses, QT or GTK
message and input boxes, according to the environment or user preferences,  so
that Bash scripts  dialogs will have a different look & feel whether there are
executed under KDE, Gnome, other wms or console.  You can also enforce the use
of ncurses, QT or GTK dialogs by setting the environment variable DIALOG:

	`tput bold`export DIALOG=DIALOG  `tput sgr0`(ncurses)
	`tput bold`export DIALOG=KDIALOG `tput sgr0`(QT)
	`tput bold`export DIALOG=ZENITY  `tput sgr0`(GTK)

`tput bold`USAGE`tput sgr0`
Either paste popup at top of your scripts or include (source) this file from
inside your scripts - or in a bash terminal - to use its functions: 
`tput bold`source /usr/local/bin/popup`tput sgr0`

`tput bold`FUNCTIONS`tput sgr0`
`tput bold`ask `tput sgr0;tput setaf 7`"test" `tput sgr0`return 0 (yes) or 1 (no)
example: `tput setaf 2`ask "question?" && do something`tput sgr0`	
`tput bold`entry `tput sgr0;tput setaf 7`"prompt:string" `tput sgr0`return the modified string:
example: `tput setaf 2`newstring=\$(prompt:string)`tput sgr0`
`tput bold`warning `tput sgr0;tput setaf 7`"text"        `tput sgr0`display warning message    
`tput bold`notice `tput sgr0;tput setaf 7`"text"         `tput sgr0`display info message    
`tput bold`error `tput sgr0;tput setaf 7`"text"          `tput sgr0`display message and abort script   
`tput bold`fileopen `tput sgr0;tput setaf 7`<directory>  `tput sgr0`select file to open   
Be careful in console mode! Pressing <Enter> immediately exits the dialog.
Use space bar to select files and directories!
`tput bold`fileshow `tput sgr0;tput setaf 7`<file>       `tput sgr0`display file   
example: `tput setaf 2`fileshow \$(fileopen /etc)`tput sgr0`
`tput bold`fileedit `tput sgr0;tput setaf 7`<file>       `tput sgr0`edit file   
`tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...    
`tput sgr0`display list of radio buttons or check options. Items should be separated by
commas.  Spaces will be replaced by "~" in list boxes.  To preselet an item,
preceed its name with "*" without space. 
example: `tput setaf 2`options=\$(choose check item1 item2 *item3)`tput sgr0`

`tput bold`CAVEATS
`tput sgr0`- cursor keys in textmode (like in other ncurses programs) don't work in aterm,
  wterm terminals . 
- fileedit dialogs width and height are ignored in kdialog.
- fileedit dialogs lose content in dialog, so we use the default editor instead.
EOFHELP
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

flag=0
which kdialog &> /dev/null && flag=$((flag | 1))
which zenity  &> /dev/null && flag=$((flag | 2))
[ "$KDE_SESSION_UID" ] && flag=$((flag & 1))
[ "$KDE_SESSION_UID" ] || flag=$((flag & 2))
[ "$ZENITY" ] && [ $ZENITY -gt 0 ] && flag=$(($flag & 2))
[ "$DISPLAY" ] || flag=$((flag | 0))
[ "$TPUT" ] && [ $TPUT -gt 0 ] && tflag=1
flag=${dflag:-$flag}

# default title
title="Popup 1.0"

# Default text editor 
edit=${edit:-$EDITOR} ; edit=${edit:-vi}

DIALOGS=(DIALOG KDIALOG ZENITY)
DIALOG=${DIALOG:-${DIALOGS[$flag]}}

# exit if dialog package not installed in text mode
# generate default ~/.dialogrc
if [ $flag -eq 0 -o "$DIALOG" == "DIALOG" ] ; then
	which dialog &>/dev/null || exec echo "dialog not found. Install this package first."
	[ -f ~/.dialogrc ] || dialog --create-rc ~/.dialogrc
	W=$(tput cols) ; H=$(tput lines)
fi  

[ "$DISPLAY" ] && eval $(xdpyinfo | sed -n 's|.*dimensions:[ ]*\([0-9]*\)x\([0-9]*\) .*|XW=$((\1*50/100));XH=$((\2*50/100))|p')

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function sizebox {
	# box width  = take 60% of terminal width or string length + 6
 	# box height = number of lines in string + 8
	type=$1 ; shift
	W=$(tput cols) ; H=$(tput lines)

	case $type in
		fileshow)  return ;;
		fileopen)  W=$(($W*70/100)) ; H=$(($H*70/100)) ; return ;;
		*)  	   W=$(($W*60/100)) ; H=$(($H*70/100)) ;;
	esac

	arg=$* ; msgW=${#arg}

	case $type in
		notice)  h=4 ;;
		ask) 	 h=6 ;;
		entry)   h=8 ;;
		choose)  msgW=$(($1 + 20)) ; h=$2 ;; 	
	esac

	[ $msgW -lt $W ] && W=$(($msgW + 6))

	case $type in
		choose)	[ $h -lt $H ] && H=$(($h + 3)) ; [ $W -lt 38 ] && W=38 ;;
		*) H=$(($msgW/$W + $h )) ;;
	esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ask {
YesNo=1
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "$title" --yesno "$*" $H $W && YesNo=0 ;;
	KDIALOG) kdialog --title "$title" --yesno "$*" && YesNo=0 ;; 
	ZENITY)  zenity --question --title "$title" --text "$*" && YesNo=0 ;; 
esac
return $YesNo
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function warn {
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "WARNING" --msgbox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --warningyesno "$*" ;;
	ZENITY)  zenity --warning --title="$title" --text="$*" ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function notice {
case $DIALOG in
	DIALOG)  sizebox notice "$*" ; dialog --title "INFO" --infobox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --msgbox "$*" ;;
	ZENITY)  zenity --info --title="$title" --text="$*" ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function error {
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "ERROR" --msgbox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --error "$*" ;;
	ZENITY)  zenity --error --title="$title" --text="$*" ;;
esac
exit 1
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function entry {
oldstring="${*##*:}" ; text="${*%%:*}:"
case $DIALOG in
	DIALOG)  sizebox entry $([ ${#oldstring} -gt ${#text} ] && echo $oldstring || echo $text) ; string=$(dialog --clear --stdout --title "$title" --inputbox "$text" $H $W "$oldstring") ;;
	KDIALOG) string=$(kdialog --title "$title" --inputbox "$text" "$oldstring") ;;
	ZENITY)  string=$(zenity --entry --title="$title" --text="$text" --entry-text="$oldstring") ;;
esac
echo $string
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileshow {
[ -f $1 ] || error "File $1 not found"
case $DIALOG in
	DIALOG)  sizebox fileshow ; dialog --clear --title "$1" --textbox "$1" $H $W ;;
	KDIALOG) kdialog --title "$title" --textbox $1 $XW $XH ;;
	ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileedit {
[ -f $1 ] || error "File $1 not found"
cp $1{,.org}
case $DIALOG in
	DIALOG)  $edit "$1" ;;
	KDIALOG) kdialog --title "$title" --textinputbox $1 "`cat $1.org`" $XW $XH > $1 ;;
	ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1.org --editable > $1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileopen {
[ -f $1 ] && d=$(dirname $1) ; [ -d $1 ] || d=${d:-$1} ; d=${d:-$1}
[ -d $d ] || d=$(dirname $d) ; d=$(echo $d/ | sed 's|//|/|')
case $DIALOG in
	DIALOG)  sizebox fileopen ; echo $(dialog --clear --stdout --title "$title" --fselect "$1" $H $W) ;;
	KDIALOG) echo $(kdialog --title "$title" --getopenfilename $d) ;;
	ZENITY)  echo $(zenity --file-selection --title="$title" --width=$XW --height=$XH --filename=$d) ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function choose {
t=${1} ; shift
[ "$t" == "radio" -o "$t" == "check" ] || error "invalid option: $t"

Items=($(echo $* | sed 's| *, *|,|g;s| |~|g;s|,| |g'))
i=0 ; j=0

items=`while [ $i -lt ${#Items[li]} ] ; do[/li]	let j++
	status=off
	echo ${Items[$i]} | grep -q "*" && status=on
	printf " %s %s %s" $j ${Items[$i]} $status 
	let i++
done`

case $DIALOG in
	DIALOG)
		sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
		index=$(dialog --clear --stdout --title "$title" --${t}list  "Select items from the list below" $(($H+6)) $W $H $items)
		[ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} ; done` ;;	
	KDIALOG)
		index=$(kdialog --title "$title" --separate-output --${t}list "Select items from the list below" ${items//\*/})
		[ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} ; done` ;;	
	ZENITY)
		sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
		items=$(echo $items | sed 's/ [0-9] /
/g;s/^1 //;s/ off/ FALSE/g;s/ on/ TRUE/g;s/\*//g' | awk '{ printf "%s %s ", $2, $1}')
		ditems=`zenity --list --${t}list --title="$title" --width=$(($W*9)) --height=$(($H*35)) --column "" --column "" --separator " " $items` ;;
esac
	echo $ditems | tr " " "
" | sed '/~/s/.*/"&"/;s/~/ /g;s/\*//g' | tr "
" " " 
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy the file where you want and save it as “popup” or any name you like . I doesn’t need to be in your path. However /usr/local/bin seems a reasonnable location. Simply source it from other scripts or in a terminal with:

source /usr/local/bin/popup

Now you can get a full description of the functions by typing pophelp.

To try it, just type:

export DIALOG=KDIALOG && notice "it works"
export DIALOG=ZENITY && notice "it works"
export DIALOG=DIALOG && notice "it works"

Hope some will find it useful.
As you guessed, I was inspired by this other thread Need GUI pop-up to edit a string

Very nice there please_try_again, thanks so much for sharing this with us. I will make every effort to use it in a script. I am going to post a different script shortly, that I found online, that will create a text file from an online repository OR, even a listing of all of the kernel files at kernel.org. Now, we just need to use it to present the most recent kernel or kernels for your selection. It is called lynxdump. So look for it here and again, that you for posting your popup script file for us to use.

Thank You,

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# use the popup library if found
which popup &>/dev/null && source $(which popup)

# use popup functions if available
function Error { declare -F | grep -q error || exec echo "Error: $*" ; error "$*" ;}
function Warn  { declare -F | grep -q warn  && warn  "$*" || echo "Warning: $*" ;}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

One possibility is to redefine some functions as in the example above to ensure that scripts will work whether the popup library is available or not. It makes it easier to redistribute them. That’s what I do.

I noticed a change between the code posted here and the one I’m using now - as I was about to mention this script in another post. Unfortunately I don’t remember why I applied this (minor) change. I must have had a good reason though. Here’s a patch which highlights the differences:

--- popup.orig  2011-09-18 13:55:13.549187116 -0700
+++ popup       2011-09-18 13:56:14.573242507 -0700
@@ -1,7 +1,7 @@
 #! /bin/bash
 #: Title       : popup
 #: Date Created: Tue Jan 18 03:04:36 PST 2011 
-#: Last Edit   : Tue Jan 18 23:20:05 PST 2011 
+#: Last Edit   : Sun Sep 18 13:55:44 PDT 2011
 #: Author      : please_try_again 
 #: Version     : 1.0
 #: Description : a simple set of ncurses/QT/GTK dialog box functions
@@ -278,10 +278,10 @@
        DIALOG)
                sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
                index=$(dialog --clear --stdout --title "$title" --${t}list  "Select items from the list below" $(($H+6)) $W $H $items)
-               [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} ; done` ;;  
+               [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} [b]| tr "~" " "[/b] ; done` ;;     
        KDIALOG)
                index=$(kdialog --title "$title" --separate-output --${t}list "Select items from the list below" ${items//\*/})
-               [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} ; done` ;;  
+               [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} [b]| tr "~" " "[/b] ; done` ;;     
        ZENITY)
                sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
                items=$(echo $items | sed 's/ [0-9] /
/g;s/^1 //;s/ off/ FALSE/g;s/ on/ TRUE/g;s/\*//g' | awk '{ printf "%s %s ", $2, $1}')

and here’s the patched version:

#! /bin/bash
#: Title       : popup
#: Date Created: Tue Jan 18 03:04:36 PST 2011 
#: Last Edit   : Sun Sep 18 13:55:44 PDT 2011
#: Author      : please_try_again 
#: Version     : 1.1
#: Description : a simple set of ncurses/QT/GTK dialog box functions
#:             : usable in other scripts
#: usage       : source /usr/local/bin/popup
#:             : type pophelp for a full description
#
#: Copy and paste this text into a text file and save it in /usr/local/bin as the file popup.
#: Import in other scripts or on the command line with: source /usr/local/bin/popup 
#: 
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# You might customize the functions by changing the variables below

# Uncomment to enforce the use of zenity dialogs in KDE
#ZENITY=1

# set default editor. If unset $EDITOR will be used.
# if EDITOR is not set, vi will be used :-)
#edit=nano

# uncomment one of the 3 lines below to enforce the use of text, 
# kdialog or zenity dialogs
#dflag=0	# dialog 
#dflag=1  	# kdialog
#dflag=2  	# zenity
#
# options for console dialog
DIALOGOPTS="--colors --shadow"

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

prg=$(basename $0)

function pophelp {
cat << EOFHELP
`tput bold`
NAME
`tput sgr0`	$prg - create ncurses, QT or GTK dialog boxes. 

`tput bold`SYNOPSIS
	ask `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`entry `tput sgr0;tput setaf 7`"prompt:text"`tput sgr0`
	`tput bold`warn  `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`notice `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`error `tput sgr0;tput setaf 7`"text"`tput sgr0`
	`tput bold`fileopen `tput sgr0;tput setaf 7`<directory>`tput sgr0`
	`tput bold`fileshow `tput sgr0;tput setaf 7`<file>`tput sgr0`
	`tput bold`fileedit `tput sgr0;tput setaf 7`<file>`tput sgr0`
	`tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...`tput sgr0`
	`tput bold`pophelp `tput sgr0;` show this help.

`tput bold`DESCRIPTION`tput sgr0`
`tput bold`popup`tput sgr0` uses the programs dialog, kdialog or zenity to create ncurses, QT or GTK
message and input boxes, according to the environment or user preferences,  so
that Bash scripts  dialogs will have a different look & feel whether there are
executed under KDE, Gnome, other wms or console.  You can also enforce the use
of ncurses, QT or GTK dialogs by setting the environment variable DIALOG:

	`tput bold`export DIALOG=DIALOG  `tput sgr0`(ncurses)
	`tput bold`export DIALOG=KDIALOG `tput sgr0`(QT)
	`tput bold`export DIALOG=ZENITY  `tput sgr0`(GTK)

`tput bold`USAGE`tput sgr0`
Either paste popup at top of your scripts or include (source) this file from
inside your scripts - or in a bash terminal - to use its functions: 
`tput bold`source /usr/local/bin/popup`tput sgr0`

`tput bold`FUNCTIONS`tput sgr0`
`tput bold`ask `tput sgr0;tput setaf 7`"test" `tput sgr0`return 0 (yes) or 1 (no)
example: `tput setaf 2`ask "question?" && do something`tput sgr0`	
`tput bold`entry `tput sgr0;tput setaf 7`"prompt:string" `tput sgr0`return the modified string:
example: `tput setaf 2`newstring=\$(prompt:string)`tput sgr0`
`tput bold`warning `tput sgr0;tput setaf 7`"text"        `tput sgr0`display warning message    
`tput bold`notice `tput sgr0;tput setaf 7`"text"         `tput sgr0`display info message    
`tput bold`error `tput sgr0;tput setaf 7`"text"          `tput sgr0`display message and abort script   
`tput bold`fileopen `tput sgr0;tput setaf 7`<directory>  `tput sgr0`select file to open   
Be careful in console mode! Pressing <Enter> immediately exits the dialog.
Use space bar to select files and directories!
`tput bold`fileshow `tput sgr0;tput setaf 7`<file>       `tput sgr0`display file   
example: `tput setaf 2`fileshow \$(fileopen /etc)`tput sgr0`
`tput bold`fileedit `tput sgr0;tput setaf 7`<file>       `tput sgr0`edit file   
`tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...    
`tput sgr0`display list of radio buttons or check options. Items should be separated by
commas.  Spaces will be replaced by "~" in list boxes.  To preselet an item,
preceed its name with "*" without space. 
example: `tput setaf 2`options=\$(choose check item1 item2 *item3)`tput sgr0`

`tput bold`CAVEATS
`tput sgr0`- cursor keys in textmode (like in other ncurses programs) don't work in aterm,
  wterm terminals . 
- fileedit dialogs width and height are ignored in kdialog.
- fileedit dialogs lose content in dialog, so we use the default editor instead.
EOFHELP
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

flag=0
which kdialog &> /dev/null && flag=$((flag | 1))
which zenity  &> /dev/null && flag=$((flag | 2))
[ "$KDE_SESSION_UID" ] && flag=$((flag & 1))
[ "$KDE_SESSION_UID" ] || flag=$((flag & 2))
[ "$ZENITY" ] && [ $ZENITY -gt 0 ] && flag=$(($flag & 2))
[ "$DISPLAY" ] || flag=$((flag | 0))
[ "$TPUT" ] && [ $TPUT -gt 0 ] && tflag=1
flag=${dflag:-$flag}

# default title
title="Popup 1.0"

# Default text editor 
edit=${edit:-$EDITOR} ; edit=${edit:-vi}

DIALOGS=(DIALOG KDIALOG ZENITY)
DIALOG=${DIALOG:-${DIALOGS[$flag]}}

# exit if dialog package not installed in text mode
# generate default ~/.dialogrc
if [ $flag -eq 0 -o "$DIALOG" == "DIALOG" ] ; then
	which dialog &>/dev/null || exec echo "dialog not found. Install this package first."
	[ -f ~/.dialogrc ] || dialog --create-rc ~/.dialogrc
	W=$(tput cols) ; H=$(tput lines)
fi  

[ "$DISPLAY" ] && eval $(xdpyinfo | sed -n 's|.*dimensions:[ ]*\([0-9]*\)x\([0-9]*\) .*|XW=$((\1*50/100));XH=$((\2*50/100))|p')

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function sizebox {
	# box width  = take 60% of terminal width or string length + 6
 	# box height = number of lines in string + 8
	type=$1 ; shift
	W=$(tput cols) ; H=$(tput lines)

	case $type in
		fileshow)  return ;;
		fileopen)  W=$(($W*70/100)) ; H=$(($H*70/100)) ; return ;;
		*)  	   W=$(($W*60/100)) ; H=$(($H*70/100)) ;;
	esac

	arg=$* ; msgW=${#arg}

	case $type in
		notice)  h=4 ;;
		ask) 	 h=6 ;;
		entry)   h=8 ;;
		choose)  msgW=$(($1 + 20)) ; h=$2 ;; 	
	esac

	[ $msgW -lt $W ] && W=$(($msgW + 6))

	case $type in
		choose)	[ $h -lt $H ] && H=$(($h + 3)) ; [ $W -lt 38 ] && W=38 ;;
		*) H=$(($msgW/$W + $h )) ;;
	esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ask {
YesNo=1
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "$title" --yesno "$*" $H $W && YesNo=0 ;;
	KDIALOG) kdialog --title "$title" --yesno "$*" && YesNo=0 ;; 
	ZENITY)  zenity --question --title "$title" --text "$*" && YesNo=0 ;; 
esac
return $YesNo
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function warn {
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "WARNING" --msgbox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --warningyesno "$*" ;;
	ZENITY)  zenity --warning --title="$title" --text="$*" ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function notice {
case $DIALOG in
	DIALOG)  sizebox notice "$*" ; dialog --title "INFO" --infobox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --msgbox "$*" ;;
	ZENITY)  zenity --info --title="$title" --text="$*" ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function error {
case $DIALOG in
	DIALOG)  sizebox ask "$*" ; dialog --clear --title "ERROR" --msgbox "$*" $H $W ;;
	KDIALOG) kdialog --title "$title" --error "$*" ;;
	ZENITY)  zenity --error --title="$title" --text="$*" ;;
esac
exit 1
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function entry {
oldstring="${*##*:}" ; text="${*%%:*}:"
case $DIALOG in
	DIALOG)  sizebox entry $([ ${#oldstring} -gt ${#text} ] && echo $oldstring || echo $text) ; string=$(dialog --clear --stdout --title "$title" --inputbox "$text" $H $W "$oldstring") ;;
	KDIALOG) string=$(kdialog --title "$title" --inputbox "$text" "$oldstring") ;;
	ZENITY)  string=$(zenity --entry --title="$title" --text="$text" --entry-text="$oldstring") ;;
esac
echo $string
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileshow {
[ -f $1 ] || error "File $1 not found"
case $DIALOG in
	DIALOG)  sizebox fileshow ; dialog --clear --title "$1" --textbox "$1" $H $W ;;
	KDIALOG) kdialog --title "$title" --textbox $1 $XW $XH ;;
	ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileedit {
[ -f $1 ] || error "File $1 not found"
cp $1{,.org}
case $DIALOG in
	DIALOG)  $edit "$1" ;;
	KDIALOG) kdialog --title "$title" --textinputbox $1 "`cat $1.org`" $XW $XH > $1 ;;
	ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1.org --editable > $1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileopen {
[ -f $1 ] && d=$(dirname $1) ; [ -d $1 ] || d=${d:-$1} ; d=${d:-$1}
[ -d $d ] || d=$(dirname $d) ; d=$(echo $d/ | sed 's|//|/|')
case $DIALOG in
	DIALOG)  sizebox fileopen ; echo $(dialog --clear --stdout --title "$title" --fselect "$1" $H $W) ;;
	KDIALOG) echo $(kdialog --title "$title" --getopenfilename $d) ;;
	ZENITY)  echo $(zenity --file-selection --title="$title" --width=$XW --height=$XH --filename=$d) ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function choose {
t=${1} ; shift
[ "$t" == "radio" -o "$t" == "check" ] || error "invalid option: $t"

Items=($(echo $* | sed 's| *, *|,|g;s| |~|g;s|,| |g'))
i=0 ; j=0

items=`while [ $i -lt ${#Items[li]} ] ; do[/li]	let j++
	status=off
	echo ${Items[$i]} | grep -q "*" && status=on
	printf " %s %s %s" $j ${Items[$i]} $status 
	let i++
done`

case $DIALOG in
	DIALOG)
		sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
		index=$(dialog --clear --stdout --title "$title" --${t}list  "Select items from the list below" $(($H+6)) $W $H $items)
		[ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} | tr "~" " " ; done` ;;	
	KDIALOG)
		index=$(kdialog --title "$title" --separate-output --${t}list "Select items from the list below" ${items//\*/})
		[ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} | tr "~" " " ; done` ;;	
	ZENITY)
		sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
		items=$(echo $items | sed 's/ [0-9] /
/g;s/^1 //;s/ off/ FALSE/g;s/ on/ TRUE/g;s/\*//g' | awk '{ printf "%s %s ", $2, $1}')
		ditems=`zenity --list --${t}list --title="$title" --width=$(($W*9)) --height=$(($H*35)) --column "" --column "" --separator " " $items` ;;
esac
	echo $ditems | tr " " "
" | sed '/~/s/.*/"&"/;s/~/ /g;s/\*//g' | tr "
" " " 
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cheers please_try_again. So good, to see the old ‘tput’ back on screen again…nostalgia all over my brain :smiley:

To be honest, I don’t know why I used tput here - must have been to please James, who loves it. I normally use escape sequences but you cannot copy/paste them. They work on all terminals though - unlike tput commands which use different syntax for terminfo and termcap (I never know which is which) and won’t work without change on any terminal (and any OS, including BSDs).

I also wondered why I wrote this function and finally figured out:

#! /bin/bash
source /usr/local/bin/popup
pophelp

To be honest, I don’t know why I used tput here - must have been to please James, who loves it. I normally use escape sequences but you cannot copy/paste them. They work on all terminals though - unlike tput commands which use different syntax for terminfo and termcap (I never know which is which) and won’t work without change on any terminal (and any OS, including BSDs).

I also wondered why I wrote this function and finally figured out:

Yes I do love using the tput command and thank you for including it. While escape sequences are very “compatible” I guess, they don’t translate well to passing code as bash scripts you can create yourself from code blocks posted here in the forum. If you can supply a down-loadable file, then its OK. But, in a modern OS like openSUSE, I don’t see any problem is using tput for color and the other things that it does. please_try_again, have you checked to see if escapes work OK when using SuSE Paste by chance?

Thank You,

Hi James,
I agree that there isn’t any problem in using tput and you do it with success in your scripts. It is certainly clearer, easier to read and to debug. I mostly use escape sequences for the compatibility reason I mentioned (although I couldn’t tell yet wich one(s) of the many OSses I’m working with still uses termcap). The other reason is that escape sequences can be “easily” embedded in strings in printf and awk commands … and it suits my scripting style better, I guess. For example, it would be possible to rewrite cfindgrub to use tput but it looks so much simpler with escape sequences. lol!

Yes, I do provide download files for scripts containing escape sequences (as you know). No, I haven’t checked in SuSE Paste.

No, I haven’t checked in SuSE Paste.

I asked about SUSE Paste becuase you can use the wget command to download the file as is intact. The execute bit still must be set, but I bet you can imbed escape sequences there too.

Thank You,

Hmmm … I have to try. But I am a little bit confused with SUSE Paste (as with many things which seem easy to a majority of people :frowning: ). For example I pasted this script (because it was too long) - see this post: Easy configuring conky with conkyconf. At a later point, I wanted to modify it … but ended up doing so as “Anonymous Alligator”. Well, I’m not (totally) anonymous and despite these allegations - I haven’t used ‘alligation’ since Middle School - don’t look like an alligator (I guess). lol!

It’s not a problem since this script is in my repo, but I just wanted to provide a link to show the code for those who would like to have a look at it. I could have put it somewhere else but wanted to try SUSE paste this time.

Hmmm … I have to try. But I am a little bit confused with SUSE Paste (as with many things which seem easy to a majority of people :frowning: ). For example I pasted this script (because it was too long) - see this post: Easy configuring conky with conkyconf. At a later point, I wanted to modify it … but ended up doing so as “Anonymous Alligator”. Well, I’m not (totally) anonymous and despite these allegations - I haven’t used ‘alligation’ since Middle School - don’t look like an alligator (I guess). lol!

It’s not a problem since this script is in my repo, but I just wanted to provide a link to show the code for those who would like to have a look at it. I could have put it somewhere else but wanted to try SUSE paste this time. http://forums.opensuse.org/clear.gif Reply](http://forums.opensuse.org/newreply.php?do=newreply&p=2385429&noquote=1) http://forums.opensuse.org/clear.gif Reply With Quote](http://forums.opensuse.org/newreply.php?do=newreply&p=2385429) Blog this Post

It does not seem possible to edit a post, but just create another. That is a problem if you want to use the same link. I have created lots of SUSE Pastes set to Never Expire as I keep updating my Bash scripts. Still, it has its good points like large scripts and it does not mess with alinements and you can designate they are bash scripts or what ever. I look at it as just another option and worth every penny it costs to use.

Thank You,

Here’s the latest version of popup. I found and fixed a bug in zenity checkbox and radio lists (which were limited to 9 entries).

#! /bin/bash
#: Title       : popup
#: Date Created: Tue Jan 18 03:04:36 PST 2011 
#: Last Edit   : Thu Oct  6 00:23:40 PDT 2011 
#: Author      : please_try_again 
#: Version     : 1.2.1
#: Description : a simple set of ncurses/QT/GTK dialog box functions
#:             : usable in other scripts
#: usage       : source /usr/local/bin/popup
#:             : type pophelp for a full description
#
#: Copy and paste this text into a text file and save it in /usr/local/bin as the file popup.
#: Import in other scripts or on the command line with: source /usr/local/bin/popup 
#: 
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# You might customize the functions by changing the variables below

# Uncomment to enforce the use of zenity dialogs in KDE
#ZENITY=1

# set default editor. If unset $EDITOR will be used.
# if EDITOR is not set, vi will be used :-)
#edit=nano

# uncomment one of the 3 lines below to enforce the use of text, 
# kdialog or zenity dialogs
#dflag=0    # dialog 
#dflag=1      # kdialog
#dflag=2      # zenity
#
# options for console dialog
DIALOGOPTS="--colors --shadow"

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

prg=$(basename $0)

function pophelp {
cat << EOFHELP
`tput bold`
NAME
`tput sgr0`    $prg - create ncurses, QT or GTK dialog boxes. 

`tput bold`SYNOPSIS
    ask `tput sgr0;tput setaf 7`"text"`tput sgr0`
    `tput bold`entry `tput sgr0;tput setaf 7`"prompt:text"`tput sgr0`
    `tput bold`warn  `tput sgr0;tput setaf 7`"text"`tput sgr0`
    `tput bold`notice `tput sgr0;tput setaf 7`"text"`tput sgr0`
    `tput bold`error `tput sgr0;tput setaf 7`"text"`tput sgr0`
    `tput bold`fileopen `tput sgr0;tput setaf 7`<directory>`tput sgr0`
    `tput bold`fileshow `tput sgr0;tput setaf 7`<file>`tput sgr0`
    `tput bold`fileedit `tput sgr0;tput setaf 7`<file>`tput sgr0`
    `tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...`tput sgr0`
    `tput bold`pophelp `tput sgr0;` show this help.

`tput bold`DESCRIPTION`tput sgr0`
`tput bold`popup`tput sgr0` uses the programs dialog, kdialog or zenity to create ncurses, QT or GTK
message and input boxes, according to the environment or user preferences,  so
that Bash scripts  dialogs will have a different look & feel whether there are
executed under KDE, Gnome, other wms or console.  You can also enforce the use
of ncurses, QT or GTK dialogs by setting the environment variable DIALOG:

    `tput bold`export DIALOG=DIALOG  `tput sgr0`(ncurses)
    `tput bold`export DIALOG=KDIALOG `tput sgr0`(QT)
    `tput bold`export DIALOG=ZENITY  `tput sgr0`(GTK)

`tput bold`USAGE`tput sgr0`
Either paste popup at top of your scripts or include (source) this file from
inside your scripts - or in a bash terminal - to use its functions: 
`tput bold`source /usr/local/bin/popup`tput sgr0`

`tput bold`FUNCTIONS`tput sgr0`
`tput bold`ask `tput sgr0;tput setaf 7`"test" `tput sgr0`return 0 (yes) or 1 (no)
example: `tput setaf 2`ask "question?" && do something`tput sgr0`    
`tput bold`entry `tput sgr0;tput setaf 7`"prompt:string" `tput sgr0`return the modified string:
example: `tput setaf 2`newstring=\$(prompt:string)`tput sgr0`
`tput bold`warning `tput sgr0;tput setaf 7`"text"        `tput sgr0`display warning message    
`tput bold`notice `tput sgr0;tput setaf 7`"text"         `tput sgr0`display info message    
`tput bold`error `tput sgr0;tput setaf 7`"text"          `tput sgr0`display message and abort script   
`tput bold`fileopen `tput sgr0;tput setaf 7`<directory>  `tput sgr0`select file to open   
Be careful in console mode! Pressing <Enter> immediately exits the dialog.
Use space bar to select files and directories!
`tput bold`fileshow `tput sgr0;tput setaf 7`<file>       `tput sgr0`display file   
example: `tput setaf 2`fileshow \$(fileopen /etc)`tput sgr0`
`tput bold`fileedit `tput sgr0;tput setaf 7`<file>       `tput sgr0`edit file   
`tput bold`choose radio | check `tput sgr0;tput setaf 7`item1,item2,*item3 ...    
`tput sgr0`display list of radio buttons or check options. Items should be separated by
commas.  Spaces will be replaced by "~" in list boxes.  To preselet an item,
preceed its name with "*" without space. 
example: `tput setaf 2`options=\$(choose check item1 item2 *item3)`tput sgr0`

`tput bold`CAVEATS
`tput sgr0`- cursor keys in textmode (like in other ncurses programs) don't work in aterm,
  wterm terminals . 
- fileedit dialogs width and height are ignored in kdialog.
- fileedit dialogs lose content in dialog, so we use the default editor instead.
EOFHELP
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

flag=0
which kdialog &> /dev/null && flag=$((flag | 1))
which zenity  &> /dev/null && flag=$((flag | 2))
[ "$KDE_SESSION_UID" ] && flag=$((flag & 1))
[ "$KDE_SESSION_UID" ] || flag=$((flag & 2))
[ "$ZENITY" ] && [ $ZENITY -gt 0 ] && flag=$(($flag & 2))
[ "$DISPLAY" ] || flag=$((flag | 0))
[ "$TPUT" ] && [ $TPUT -gt 0 ] && tflag=1
flag=${dflag:-$flag}

# default title
title="Popup 1.0"

# Default text editor 
edit=${edit:-$EDITOR} ; edit=${edit:-vi}

DIALOGS=(DIALOG KDIALOG ZENITY)
DIALOG=${DIALOG:-${DIALOGS[$flag]}}

# exit if dialog package not installed in text mode
# generate default ~/.dialogrc
if [ $flag -eq 0 -o "$DIALOG" == "DIALOG" ] ; then
    which dialog &>/dev/null || exec echo "dialog not found. Install this package first."
    [ -f ~/.dialogrc ] || dialog --create-rc ~/.dialogrc
    W=$(tput cols) ; H=$(tput lines)
fi  

[ "$DISPLAY" ] && eval $(xdpyinfo | sed -n 's|.*dimensions:[ ]*\([0-9]*\)x\([0-9]*\) .*|XW=$((\1*50/100));XH=$((\2*50/100))|p')

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function sizebox {
    # box width  = take 60% of terminal width or string length + 6
     # box height = number of lines in string + 8
    type=$1 ; shift
    W=$(tput cols) ; H=$(tput lines)

    case $type in
        fileshow)  return ;;
        fileopen)  W=$(($W*70/100)) ; H=$(($H*70/100)) ; return ;;
        *)         W=$(($W*60/100)) ; H=$(($H*70/100)) ;;
    esac

    arg=$* ; msgW=${#arg}

    case $type in
        notice)  h=4 ;;
        ask)      h=6 ;;
        entry)   h=8 ;;
        choose)  msgW=$(($1 + 20)) ; h=$2 ;;     
    esac

    [ $msgW -lt $W ] && W=$(($msgW + 6))

    case $type in
        choose)    [ $h -lt $H ] && H=$(($h + 3)) ; [ $W -lt 38 ] && W=38 ;;
        *) H=$(($msgW/$W + $h )) ;;
    esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ask {
YesNo=1
case $DIALOG in
    DIALOG)  sizebox ask "$*" ; dialog --clear --title "$title" --yesno "$*" $H $W && YesNo=0 ;;
    KDIALOG) kdialog --title "$title" --yesno "$*" && YesNo=0 ;; 
    ZENITY)  zenity --question --title "$title" --text "$*" && YesNo=0 ;; 
    *) return 1 ;;
esac
return $YesNo
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function warn {
case $DIALOG in
    DIALOG)  sizebox ask "$*" ; dialog --clear --title "WARNING" --msgbox "$*" $H $W ;;
    KDIALOG) kdialog --title "$title" --warningyesno "$*" ;;
    ZENITY)  zenity --warning --title="$title" --text="$*" ;;
    *) return 1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function notice {
case $DIALOG in
    DIALOG)  sizebox notice "$*" ; dialog --title "INFO" --infobox "$*" $H $W ;;
    KDIALOG) kdialog --title "$title" --msgbox "$*" ;;
    ZENITY)  zenity --info --title="$title" --text="$*" ;;
    *) return 1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function error {
case $DIALOG in
    DIALOG)  sizebox ask "$*" ; dialog --clear --title "ERROR" --msgbox "$*" $H $W ;;
    KDIALOG) kdialog --title "$title" --error "$*" ;;
    ZENITY)  zenity --error --title="$title" --text="$*" ;;
    *) return 1 ;;
esac
exit 1
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function entry {
oldstring="${*##*:}" ; text="${*%%:*}:"
case $DIALOG in
    DIALOG)  sizebox entry $([ ${#oldstring} -gt ${#text} ] && echo $oldstring || echo $text) ; string=$(dialog --clear --stdout --title "$title" --inputbox "$text" $H $W "$oldstring") ;;
    KDIALOG) string=$(kdialog --title "$title" --inputbox "$text" "$oldstring") ;;
    ZENITY)  string=$(zenity --entry --title="$title" --text="$text" --entry-text="$oldstring") ;;
    *) return 1 ;;
esac
echo $string
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileshow {
[ -f $1 ] || error "File $1 not found"
case $DIALOG in
    DIALOG)  sizebox fileshow ; dialog --clear --title "$1" --textbox "$1" $H $W ;;
    KDIALOG) kdialog --title "$title" --textbox $1 $XW $XH ;;
    ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1 ;;
    *) return 1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileedit {
[ -f $1 ] || error "File $1 not found"
cp $1{,.org}
case $DIALOG in
    DIALOG)  $edit "$1" ;;
    KDIALOG) kdialog --title "$title" --textinputbox $1 "`cat $1.org`" $XW $XH > $1 ;;
    ZENITY)  zenity --text-info --title="$title" --width=$XW --height=$XH --filename=$1.org --editable > $1 ;;
    *) return 1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function fileopen {
[ -f $1 ] && d=$(dirname $1) ; [ -d $1 ] || d=${d:-$1} ; d=${d:-$1}
[ -d $d ] || d=$(dirname $d) ; d=$(echo $d/ | sed 's|//|/|')
case $DIALOG in
    DIALOG)  sizebox fileopen ; echo $(dialog --clear --stdout --title "$title" --fselect "$1" $H $W) ;;
    KDIALOG) echo $(kdialog --title "$title" --getopenfilename $d) ;;
    ZENITY)  echo $(zenity --file-selection --title="$title" --width=$XW --height=$XH --filename=$d) ;;
    *) return 1 ;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function choose {
t=${1} ; shift
[ "$t" == "radio" -o "$t" == "check" ] || error "invalid option: $t"

Items=($(echo $* | sed 's| *, *|,|g;s| |~|g;s|,| |g'))
i=0 ; j=0

items=`while [ $i -lt ${#Items
[li]} ] ; do[/li]    let j++
    status=off
    echo ${Items[$i]} | grep -q "*" && status=on
    printf " %s %s %s" $j ${Items[$i]} $status 
    let i++
done`

case $DIALOG in
    DIALOG)
        sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
        index=$(dialog --clear --stdout --title "$title" --${t}list  "Select items from the list below" $(($H+6)) $W $H $items)
        [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} | tr "~" " " ; done` ;;    
    KDIALOG)
        index=$(kdialog --title "$title" --separate-output --${t}list "Select items from the list below" ${items//\*/})
        [ "$index" == "" ] || ditems=`for i in $(echo $index | tr -d "\"") ; do let i-- ; echo ${Items[$i]} | tr "~" " " ; done` ;;    
    ZENITY)
        sizebox choose  $(echo $* | tr "," "
" | sed 's|^ *||;s|^\*||' | wc -L) $(echo $* | sed 's|[^,]||g' | wc -L)
        items=$(echo $items | sed 's|off \([0-9]\)|FALSE
\1|g;s|on \([0-9]\)|TRUE
\1|g;s|off$|FALSE|;s|on$|TRUE|' | awk '{ printf "%s %s ",  $3, $2 }')
        ditems=`zenity --list --${t}list --title="$title" --width=$(($W*9)) --height=$(($H*35)) --column "" --column "" --separator " " $items` ;;
    *) return 1 ;;
esac
    echo $ditems | tr " " "
" | sed '/~/s/.*/"&"/;s/~/ /g;s/\*//g' | tr "
" " " 
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This script is also included in the vmscripts package, as it is used by other scripts to display dialog boxes and error messages.

Well … another advantage of escape sequences over tput is that tput produces garbage if LANG is set to POSIX and LC_ALL is empty.

Just try:

LANG=POSIX LC_ALL="" *somescript*

where somescript is a script containing tput commands.

Please disregard the previous post. It’s another problem… I’ll find out.

Well I gave the terminal command:

LANG=POSIX LC_ALL="" sgtb

And sqtb still worked like a champ even though sgtb does use tput for color.

please_try_again Please disregard the previous post. It’s another problem… I’ll find out.

Only thing I can say for sure is that just like oldcpu, you are starting to talk to yourself. That is the first sign of trouble. lol!

Thank You,

I know. :frowning:
The ouput of rpm -i was different (date/time format) as I suddenly switched to a POSIX terminal and ran the script I was working on. Adding LC_ALL=C before the command solves the problem. Actually we should always think about that when parsing commands (such as fdisk for example) which output varies with different locale settings.

Please the

export DIALOG
command could be used to send a login dialog box
from server machine to several client terminals within a local network running Ubuntu system,
for example ?