Linux Apprentice: Improve Bash Shell Scripts Using Dialog
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Home, My Backup Data Center
- What's the tweeting protocol?
- New Products
- RSS Feeds
- Readers' Choice Awards
- Dart: a New Web Programming Experience
- Reply to comment | Linux Journal
12 hours 53 min ago - Reply to comment | Linux Journal
15 hours 25 min ago - Reply to comment | Linux Journal
16 hours 43 min ago - great post
17 hours 18 min ago - Google Docs
17 hours 40 min ago - Reply to comment | Linux Journal
22 hours 28 min ago - Reply to comment | Linux Journal
23 hours 15 min ago - Web Hosting IQ
1 day 49 min ago - Thanks for taking the time to
1 day 2 hours ago - Linux is good
1 day 4 hours ago
Enter to Win an Adafruit Prototyping Pi Plate Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Prototyping Pi Plate Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- Next winner announced on 5-21-13!
Free Webinar: Linux Backup and Recovery
Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.
In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.




Comments
Echo current actions to dialog
Hi, thanks, your scripts have helped me to get started. I have now written one to display a menu which allows me to select one of my servers to backup (using rsync). I also looked at you 'gauge' script and would like to find a way to use this to echo current progress - the filename which rsync is transfering. Below is my backup script, so far...
-------------------------------------------------------------------------
#!/bin/sh
fileroot=/bin
array=(Ystradgynlais Brecon Llandrindod Newtown Welshpool Machynlleth Corporate)
n=1
for item in ${array[@]}
do
menuitems="$menuitems $n ${item}"
let n+=1
done
dialog --menu \
"Select server to backup" \
14 40 7 $menuitems 2> /tmp/$$
if [ $? -gt 0 ]; then
rm -f /tmp/$$
clear
echo "Operation Cancelled"
exit 0
fi
selection=${array[$(cat /tmp/$$) -1]}
echo "You selected $selection"
basedest="/home/backups/manual"
if [ "$selection" = "Machynlleth" ] ; then
destination=$basedest/"canolfan_$(date +%Y%m%d)"
server="172.16.20.20"
elif [ "$selection" = "Brecon" ] ; then
destination=$basedest/"brecon_$(date +%Y%m%d)"
server="172.16.86.7"
elif [ "$selection" = "Llandrindod" ] ; then
destination=$basedest/"llandrindod_$(date +%Y%m%d)"
server="172.19.166.7"
elif [ "$selection" = "Welshpool" ] ; then
destination=$basedest/"welshpool_$(date +%Y%m%d)"
server="172.16.155.6"
elif [ "$selection" = "Newtown" ] ; then
destination=$basedest/"newtown_$(date +%Y%m%d)"
server="172.19.170.7"
elif [ "$selection" = "Ystradgynlais" ] ; then
destination=$basedest/"ystradgynlais_$(date +%Y%m%d)"
server="172.19.171.7"
elif [ "$selection" = "Corporate" ] ; then
destination=$basedest/"corporate_$(date +%Y%m%d)"
server="172.16.15.9"
else
exit 0
fi
rsync -e ssh -avz --exclude-from=/usr/sbin/excludes.txt root@$server:/home $destination/
rsync -e ssh -avz root@$server:/etc/samba $destination/samba/
rsync -e ssh -avz root@$server:/etc/passwd $destination/passwd/
rsync -e ssh -avz root@$server:/etc/group $destination/group/
exit 0
-------------------------------------------------------------------------
Any help would be much appreciated.
Mike.
bisca command of unix
help me by line command of unix
Gauge and others
Funnily your bash script using --guage works even if misspelled, i.e. the correct parameter is --gauge.
Another version of the script would look as follows:
#!/bin/bash
{ for I in $(seq 1 100) ; do
echo $I
sleep 0.01
done
echo 100; } | dialog --shadow --gauge "Progress" 6 70 0
In this case the bar stays a 100 in the end.
In any case thanks a lot for this article. This is exactly what I was looking for.
I got inspired to make a file selection menu:
#!/bin/sh
# File or Directory selection menu with dialog
fileroot=/bin
array=( $(ls $fileroot) )
n=0
for item in ${array[@]}
do
menuitems="$menuitems $n ${item}"
let n+=1
done
dialog --title "Select a file" --menu \
"Choose one of the following or press to exit" \
14 40 6 $menuitems 2> /tmp/$$
if [ $? -gt 0 ]; then
rm -f /tmp/$$
clear
echo "Interrupted"
exit 0
fi
selection=${array[$(cat /tmp/$$)]}
echo "You selected $selection"
George
Menu with array
The menu with array is really intresting, but what if instead of use an array of file-names, you use an array of elements that have a space in the middle of the element?
Two ways to implement dynamic menus without arrays
Also see here: http://pastebin.com/f5a053e2a
#! /bin/sh
# If MAX_ARG_PAGES is 32 and page size is 4KB, then there is only 128kB for environment variables and arguments.
# Since dynamic menu items are passed in via command line, only return about 100kB of data or less.
# Any more, and there will be an error when launching the menu.
FILEMENU_MAXNUMBEROFFILES=60
FILEMENU_MAXAGEINDAYS=180
function listFiles() {
DirPath=$1
ModifyTime=$2
find "$DirPath" -maxdepth 1 -mindepth 1 -type f -mtime "$ModifyTime" -print
}
function listFilesForMenuXarg() {
DirPath=$1
ModifyTime=$2
listFiles "$DirPath" "$ModifyTime" | tail -n $FILEMENU_MAXNUMBEROFFILES | while read filePath; do
echo -e -n "$(basename "$filePath")\0000$(date -r /opt "+%Y-%m-%d") $(cat "$filePath" | wc -c)\0000"
done
}
function fileMenuXarg() {
DirPath=$1
while [ true ]; do
exec 3>&1
exec 4>&1
fileName=$(listFilesForMenuXarg "$DirPath" "-$FILEMENU_MAXAGEINDAYS" 0>&4 | xargs -0 dialog --input-fd 4 --default-item "$fileName" --menu "Xarg Test - Select a file." 0 0 0 2>&1 1>&3)
returnCode=$?
exec 3>&-
exec 4>&-
if [ $returnCode -ne 0 ]; then
return
fi
cat "$DirPath/$fileName" | less
done
}
function listFilesForMenuSet() {
DirPath=$1
ModifyTime=$2
listFiles "$DirPath" "$ModifyTime" | tail -n $FILEMENU_MAXNUMBEROFFILES | while read filePath; do
echo "$(basename "$filePath")"
echo "$(date -r /opt "+%Y-%m-%d") $(cat "$filePath" | wc -c)"
done
}
function fileMenuSet() {
DirPath=$1
while [ true ]; do
IFS=$'\n'
set $(listFilesForMenuSet "$DirPath" "-$FILEMENU_MAXAGEINDAYS")
IFS=$' \t\n'
exec 3>&1
fileName=$(dialog --default-item "$fileName" --menu "Set Test - Select a file." 0 0 0 "$@" 2>&1 1>&3)
exec 3>&-
returnCode=$?
if [ $returnCode -ne 0 ]; then
return
fi
cat "$DirPath/$fileName" | less
done
}
# You must have some files in your home directory for this example to work.
fileMenuSet "$HOME"
fileMenuXarg "$HOME"
array of elements that have a space in the middle of the element
It would be realy nice to see the answer to this question. When quoting and escape characters don't work, it's only guessing to what the dialog programmers choose to let this work. If an answer exists, please let me know. Thanks in advance.
array of elements that have a space in the element
Found 1 way to do it, although it is not a very elegant way, so I am curious if somebody can come up with a better solution.
The solution I use now is to build up the complete dialog command in a file and then execute the file within the shell. For example build the above $menuitems like:
Tag=“Cron”
Item=“Perform cron administration”
echo “$Tag” > /tmp/menuitems.$$
echo “$Item” >> /tmp/menuitems.$$
Tag=“Global Reports”
Item=“Show Global Reports”
echo “$Tag” >> /tmp/menuitems.$$
echo “$Item” >> /tmp/menuitems.$$
Tag=”Log files”
Desc=”Perform Logfile Management”
echo “$Tag” >> /tmp/menuitems.$$
echo “$Item” >> /tmp/menuitems.$$
#(better to build this up in loop of course)
Title=”Task Manager”
export Title
MenuHeight=6
export MenuHeight
# now build the dialog command
BldMenu="dialog --clear --title \"$Title\" \
--menu \" Use arrow keys, or first character \n\
Select with \n\
Your choice:\" 30 82 $MenuHeight \
$(cat /tmp/menuitems.$$|while read item;do echo "\"${item}\"";done) \
2>/tmp/dialans.$$"
# put the dialog command in a file
echo ${BldMenu} >/tmp/dialbuild.$$
# execute the dialbuild file (note the dot-space in the front)
. /tmp/dialbuild.$$
#At least it works (:-|)
Dynamic Menus with Spaces in the elements
Here is how I figured out how to do this. It has to do with how the strings get delimited in bash. For this example I build a list of menu items from a pre-existing array of interface names. I build the array by referencing the count of its elements as the index to write to (thus each assignment adds another element to the end). So if var_ifarray has only one element then menulist will have that element as the tag and some text as the description.
declare menulist
declare i
menulist=( )
for i in ${var_ifarray[@]}; do
if [ $? -ne 0 ]; then
menulist[${#menulist[@]}]="$i"
menulist[${#menulist[@]}]="interface $i"
fi
done
#if you want to just quickly test this you can just define
# a bunch of elements like so:
# menulist[${#menulist[@]}]="1"
# menulist[${#menulist[@]}]="Option 1"
# menulist[${#menulist[@]}]="2"
# menulist[${#menulist[@]}]="Option 2"
# This IFS environment change is what fixes the issue of spaces breaking the line from variables.
IFS=$'\n'
$DIALOG --title "Multiple Item list" \
--menu "Choose one" 15 55 5 \
$(printf "${menulist[*]}") 2>$local_dialogresponses
Dynamic Menus with Spaces in the elements
# ----- menu ----- #
options=(wipe erase delete "zap it")
i=0
for item in "${options[@]}"; do
array[i++]=$item
array[i++]=""
done
dialog --menu "Shall I ... ?" 11 30 ${#options[@]} "${array[@]}"
# ----- checklist ----- #
options=(wipe erase delete "zap it")
i=0; counter=0
for item in "${options[@]}"; do
(( counter++ ))
array[i++]=$counter
array[i++]=$item
array[i++]="off"
done
dialog --checklist "Shall I ... ?" 11 50 ${#options[@]} "${array[@]}"
Errors when running dialog --menu
I tried running Listing 3 and Linux spit out tons of errors about "line 18: [: too many agruments" and on other lines, too. Is this because I have a (possibly) outdated dialog installation, or errors in the shell script?
Why the answers are not shown
I would like to read the answers to the problems in this secction.
Need help on this topic
Hi,
I am using a alias command in the .bashrc in root as
alias hi="cd /mnt/tejas/software/"
so when i type hi in my konsole then it will move to software folder and there i am executing a shell script call ./manftest.sh whihc is a menu method os redirecting user to different path like
The manftest.sh shell will look like
1. software1
2. software2
3. software3
so if user selects option2 then he will moved to different path according to the choice.
but when i move a user like this the same path is not replicated on the title bar, i need the redirected path to be displayed in title bar so help me.
Re: Strictly On-Line: Linux Apprentice: Improve Bash Shell Scrip
It's realy an usefull article ( and I am a beginer in this ) !!! Only the question remain - can/t find tutorials about - " How can I pass one menu to other without the window blinking ? I've tryed to understand info white pages , but it's not a such helpfull staff . "
Thanks in advance
Alex
Re: Strictly On-Line: Linux Apprentice: Improve Bash Shell Scrip
It would be very nice if I could have more than one inputbox at the same window (like a form with various fields to fill in)...Is there any way to do that?
good idear
which dialog 1.0
you can user the option: --form
good luck.
--form
How to use --form. I tried it but got errors
Thanks
Looking for examples using
Looking for examples using --form to use in dialog box. Can anyone help?
Thanks
Form
The form idea is wonderful but how to read each field and save it in a variable --- Thanks for your extra help
Shell Script - Dialog Form Example
dialog --backtitle "Dialog Form Example" --title "Dialog - Form" \
--form "\nDialog Sample Label and Values" 25 60 16 \
"Form Label 1:" 1 1 "Value 1" 1 25 25 30 \
"Form Label 2:" 2 1 "Value 2" 2 25 25 30 \
"Form Label 3:" 3 1 "Value 3" 3 25 25 30 \
"Form Label 4:" 4 1 "Value 4" 4 25 25 30 \
"Form Label 5:" 5 1 "Value 5" 5 25 25 30 \
"Form Label 6:" 6 1 "Value 6" 6 25 25 30 \
"Form Label 7:" 7 1 "Value 7" 7 25 25 30 \
"Form Label 8:" 8 1 "Value 8" 8 25 25 30 \
2>/tmp/form.$$
echo `cat /tmp/form.$$`
rm /tmp/form.$$
dialog - Form
The form is great but how to save each field in a variable --- Thanks for your the help
Dialog - Form
dialog --backtitle "Dialog Form Example" --title "Dialog - Form" \
--form "\nDialog Sample Label and Values" 25 60 16 \
"Form Label 1:" 1 1 "Value 1" 1 25 25 30 \
"Form Label 2:" 2 1 "Value 2" 2 25 25 30 \
"Form Label 3:" 3 1 "Value 3" 3 25 25 30 \
"Form Label 4:" 4 1 "Value 4" 4 25 25 30 \
"Form Label 5:" 5 1 "Value 5" 5 25 25 30 \
"Form Label 6:" 6 1 "Value 6" 6 25 25 30 \
"Form Label 7:" 7 1 "Value 7" 7 25 25 30 \
"Form Label 8:" 8 1 "Value 8" 8 25 25 30 \
2>/tmp/form.$$
FORM=(`cat /tmp/form.$$ | tr '\\n' ' '`)
for i in 0 1 2 3 4 5 6 7;
do
echo "$FORM[$i]"
done
All the fiedls will be in the variable FORM.
Dialog - Form
dialog --backtitle "Dialog Form Example" --title "Dialog - Form" \
--form "\nDialog Sample Label and Values" 25 60 16 \
"Form Label 1:" 1 1 "Value 1" 1 25 25 30 \
"Form Label 2:" 2 1 "Value 2" 2 25 25 30 \
"Form Label 3:" 3 1 "Value 3" 3 25 25 30 \
"Form Label 4:" 4 1 "Value 4" 4 25 25 30 \
"Form Label 5:" 5 1 "Value 5" 5 25 25 30 \
"Form Label 6:" 6 1 "Value 6" 6 25 25 30 \
"Form Label 7:" 7 1 "Value 7" 7 25 25 30 \
"Form Label 8:" 8 1 "Value 8" 8 25 25 30 \
2>/tmp/form.$$
FORM=(`cat /tmp/form.$$ | tr '\\n' ' '`)
for i in 0 1 2 3 4 5 6 7;
do
echo "$FORM[$i]"
done
All the fiedls will be in the variable FORM.
Direct output to bash
Direct output to bash variable:
exec 3>&1
FORM=$(dialog --backtitle "Dialog Form Example" --title "Dialog - Form" \
--form "\nDialog Sample Label and Values" 25 60 16 \
"Form Label 1:" 1 1 "Value 1" 1 25 25 30 \
"Form Label 2:" 2 1 "Value 2" 2 25 25 30 \
"Form Label 3:" 3 1 "Value 3" 3 25 25 30 \
"Form Label 4:" 4 1 "Value 4" 4 25 25 30 \
"Form Label 5:" 5 1 "Value 5" 5 25 25 30 \
"Form Label 6:" 6 1 "Value 6" 6 25 25 30 \
"Form Label 7:" 7 1 "Value 7" 7 25 25 30 \
"Form Label 8:" 8 1 "Value 8" 8 25 25 30 \
2>&1 1>&3)
exec 3>&-
echo $FORM
for i in 0 1 2 3 4 5 6 7;
do
echo "$FORM[$i]"
done
Ljubomir Ljubojevic