I have developed a menu in bash with some options(only backup will be included here), one of these options is to backup, however whenever I close the shell, the backup command runs and makes a backup by it self.
I tried adding break and exit before ;; but it just stops the whole script.
#!/bin/bash
menu=$(echo "Choose operation [1]Hi [2]Backup")
echo "$menu"
while [ $# == 0 ]; do
read options
case "$options" in
1 )
echo "HI"
echo "$menu"
;;
2 )
dir="/home/backups"
bckup="$(date +%d%b%Y_%H%M)"
mkdir $dir/$bckup
cat /etc/passwd >> $dir/$bckup/"DB$bckup".txt
dialog --title "DATABASE" --msgbox " Ready to backup user database. \n
press <Enter> to start or <Esc> to cancel." 10 50
# Return status of non-zero indicates cancel
if [ "$?" != "0" ]
then
dialog --title "BACKUP" --msgbox " Backup was canceled at your request." 10 50
else
dialog --title "BACKUP" --infobox " Backup in process..." 10 50 ; sleep 1
tar czf $dir/$bckup.tgz -C $dir/$bckup . >|/tmp/ERRORS$$ 2>&1
# zero status indicates backup was successful
if [ "$?" = "0" ]
then
dialog --title "BACKUP" --msgbox " Backup completed successfully." 10 50
else
dialog --title "BACKUP" --msgbox "Backup failed Press <Enter> to see error log." 10 50
dialog --title "Error Log" --textbox /tmp/ERRORS$$ 22 72
fi
fi
rm -r -f $dir/$bckup
rm -f /tmp/ERRORS$$
clear
echo "$menu"
;;
*)
echo "Invalid, Please choose a valid option"
;;
esac
done
exit
What happens when you type EOF to:
You don’t test whether that worked. It is likely that
optionscontains the previous value, and that you previously tried backup. If the diagnosis is correct, then the fix is pretty simple:You could (should?) provide an explicit exit option too, but this should protect you from unexpected backups after you type Control-D or whatever it is you use as an EOF indication to the terminal.
A slightly more radical reorganization uses:
or:
It is a question of shell semantics.
while [ $# == 0 ]does a string equality comparison of the number of arguments$#against0.while [ $# != 0 ]does a string inequality comparison of the number of arguments and 0.while [ $# -ne 0 ]does a numeric inequality comparison of the number of arguments and 0.while [ $# -eq 0 ]does a numeric equality comparison of the number of arguments and 0.Note that this is the converse of the Perl convention, where:
$x == 0is numeric equality$x != 0is numeric inequality$x eq 0is string equality$x ne 0is string inequalityIn all pairs of cases, the result is the same when the comparisons are (in)equality and the values are expressed conventionally (using the minimum number of digits and expressed as an integer). The numeric versus string comparison matters for ordering comparisons (
>,<,>=,<=).Your original code loops on
while [ $# == 0 ](while there are no positional arguments). If there are any arguments (so$# != 0or$# > 0, since the number of arguments is never negative), the loop is never entered.The first of my rewrites checks that there are no arguments before entering the
while read optionsloop.The second of my rewrites exits early if there are any arguments and so does not enter the
while read optionsloop at all when arguments are present. They are equivalent except that the first rewrite has the body of the loop nested one level more deeply.Note that none of the code shown ever changes the number of positional parameters (number of arguments). You’d do that with
set -- arg1 arg2 ...if you really wanted to, but you probably don’t.