how to create a do-while loop using bash? - bash

I want the Menu to run once and then ask if the user wants it to run again, if they say yes it it continues to run until they say no. I saw some examples online but im not understanding how to implement it.
#Menu
echo "Menu"
echo "1. Display the message that indicates when the <script> command stared"
echo "2. Dispay the message that indicates when the <script> command terminated"
echo "3. game score"
read answer
if[[ $answer == 1 ]]; then
echo""
elif[[ $answer == 2 ]]; then
echo""
elif [[ $answer == 3]]; then
fi
echo "Do you want to repeat this routine?(Y/N)"
read yesno

Other approach:
#the action functions
do_script_start() {
echo "this is a message - start"
}
do_script_term() {
echo "this is a message - term"
}
do_score() {
echo "this is a game score"
}
# main
ans=(
"Display the message that indicates when the <script> command stared"
"Dispay the message that indicates when the <script> command terminated"
"game score"
"exit menu"
)
PS3="Select what you want>"
select answer in "${ans[#]}"
do
case "$REPLY" in
1) do_script_start ;;
2) do_script_term ;;
3) do_score ;;
4) break ;;
esac
done
echo "here..."

Related

Creating Menus Shell Scripting

I'm started learning shell scripting, and I'm trying to figure out a way to add an option that returns the user back to the menu.
for example:
5) echo "Return to the menu"
echo "Return back to the menu? ";;
Hear is the script on hand:
echo "1. I'm number one"
echo "2. I'm number two"
echo "3. I'm number three"
echo "4. Exit from menu "
echo -n "Enter one the following numbers:"
while :
do
read choice
case $choice in
1) echo "You have selected the number one"
echo "Selected number is one";;
2) echo "You have selected the number two"
echo "Selected number is two";;
3) echo "You have selected the number three"
echo "Selected number is three";;
4) echo "Exiting after the information have been received by both devices" # Referring to the TCP/IP protocol. The information has to be established by both client and device to act like a server before data is sent. Ok I'm showing of here :)
exit;
esac
echo -n "Enter one of the four options"
done # Sorry if there are errors in the this code, I wrote it on the fly :)
You can also use select to create a menu
#! /bin/bash
opts=( "I'm number one" "I'm number two" "I'm number three" "Exit from menu" )
PS3="Enter one the following numbers:"
select o in "${opts[#]}"
do
case "$REPLY" in
1) echo "You have selected the number one: $o"
echo "Selected number is one";;
2) echo "You have selected the number two: $o"
echo "Selected number is two";;
3) echo "You have selected the number three: $o"
echo "Selected number is three";;
4) echo "Exiting after the information have been received by both devices" # Referring to the TCP/IP protocol. The information has to be established by both client and device to act like a server before data is sent. Ok I'm showing of here :)
exit;;
esac
done
TLDR ;) Put the usage in it's own function and call that when you want
I'd do something like this(shortened for brevity)
#!/bin/bash
printUsage() {
echo "Enter one the following options:"
echo "1: do 1 stuff"
echo "x: exit"
# add more as necessary
}
printUsage
while true; do
read choice
case $choice in
1)
echo "You have selected the number one"
break
;;
x)
echo "k thx bye"
exit
;;
*)
echo ""
echo "Invalid option: $choice"
echo ""
printUsage
;;
esac
done
echo "Doing $choice stuff"
To add a return to menu feature, try this:
Add a variable accessMenu, set it to true, and update the while loop condition as so, and set accessMenu to false first thing in the loop...
accessMenu=true
while [[ $accessMenu -eq true ]]; do
accessMenu=false
... (code)
done
Lastly, in the case that you want to enable returning to the menu, set the variable to true, and it will pass the condition in the while loop to run again.
Ok so i figured that i can wrap it up inside a function and then run the function whenever i wanted to return back to the menu.
myfunc()
{
echo "1. I'm number one"
echo "2. I'm number two"
echo "3. I'm number three"
echo "4. Return to the menu"
echo "5. Exit from menu "
echo -n "Enter one the following numbers:"
while :
do
read choice
case $choice in
1) echo "You have selected the number one"
echo "Selected number is one";;
2) echo "You have selected the number two"
echo "Selected number is two";;
3) echo "You have selected the number three"
echo "Selected number is three";;
4) echo "Return to the menu"
myfunc;;
5) echo "Exiting after the information have been received by both devices"
exit;
esac
echo -n "Enter one of the four options"
done
}
myfunc

Return to previous commands in bash script?

I'm trying to implement a prev option in my bash script to go back to the previous "menu", as well as a way for the script to ask for user input again if no variable is set for $name.
Heres my bash script:
#!/bin/bash
#Menu() {
for (( ; ; ))
do
beginORload=
echo "Choose option:"
echo "1 - Begin"
echo "2 - Load"
read -p "?" beginORload
#}
#Begin() {
if [ "$beginORload" -eq "1" ]
then
clear
for (( ; ; ))
do
echo "Beginning. What is your name?"
read -p "?" name
#If "prev" specified, go back to #Menu()
if [ "$name" -eq "prev" ]
then
Menu
fi
#If nothing specified, return to name input
if [ -z ${name+x} ]
then
Begin
else
break
fi
echo "Hi $name !"
done
fi
done
In batch, I could simply do:
:menu
echo Choose option:
echo 1 - Begin
echo 2 - Load
[...]
:begin
[...]
if "%name%==prev" goto menu
if "%name%==" goto begin
the issue is I keep running into errors all over the place, and I can't figure out what to type to get it to work
im running Yosemite btw. Thankyou
Something like this is close to what you expect:
while [[ $answer -ne '3' ]];do
echo "Choose option:"
echo "1 - Begin"
echo "2 - Load"
echo "3 - Exit"
read -p "Enter Answer [1-2-3]:" answer
case "$answer" in
1) while [[ "$nm" == '' ]];do read -p "What is your Name:" nm;done # Keep asking for a name if the name is empty == ''
if [[ $nm == "prev" ]];then nm=""; else echo "Hello $nm" && break; fi # break command breaks the while wrapper loop
;;
2) echo 'Load' ;;
3) echo 'exiting...' ;; # Number 3 causes while to quit.
*) echo "invalid selection - try again";; # Selection out of 1-2-3 , menu reloaded
esac # case closing
done # while closing
echo "Bye Bye!"
As a general idea you can wrap up your case selection in a while loop which will break under certain circumstances (i.e If Option 3 is selected or if a valid name is given (not blank - not prev)
PS1: In bash you compare integers with -eq , -ne, etc but you compare strings with == or !=
PS2: Check the above code online here

Updating sub-menus variables

I have a problem with this bash script:
#!/bin/bash
G=100
echo $G
main_menu()
{
while :
do
clear
echo "Select from menu"
echo "[1] Press 1 to show savings"
echo "[2] Press 2 to withdraw savings"
echo "[3] Press 3 to exit"
echo "Enter your menu choice [1-3]: \c "
read -r m_menu
case "$m_menu" in
1) option_1;;
2) option_2;;
3) exit 0;;
*) echo "\nERROR: Please select a valid menu choice";
echo "Press ENTER To Continue..." ; read ;;
esac
done
}
option_1()
{
clear
echo "Your balance is $G"
echo "\nPress ENTER to return to menu..."
read
return
}
option_2()
{
clear
echo "Withdraw savings"
read -rp "Enter amount to withdraw: " num
if [ $num -le $G ]; then
answer=$(echo $(( G - num )))
echo "Your new balance is: $answer"
echo "$answer" | tee "$G"
elif [ $num -gt $G ]; then
echo "No: not eough money in your balance"
fi
read
return
}
main_menu
The problem is the following: how do I make sure that once I withdraw savings, my saving count will be updated? Because if I withdraw $90, obviously when I return to the balance it should be $10 and yet this doesn't work for me (it still says saving balance is $100)
What can I do?
Thank you (sorry for my poor English)
You have to update G in your code.
if [ $num -le $G ]; then
G=$(( G - num ))
echo "Your new balance is: $G"

what is the best way to go back to the beginning of a script?

I have a script with several inputs, the script eventually initiates a download, once the download is complete i would like to do prompt the user to start the process over if they want to download something else.
while true;do
read -p "Is this correct? (yes/no/abort) " yno
case $yno in
[Yy]*) break;;
[Nn]*) echo "Lets Start Over" 'restart script code goes here';;
[Aa]*) exit 0;;
*) echo "Try again";;
esac
done
echo
echo "Starting $build download for $opt1 from Jenkins"
echo
while true;do
read -p "Do you want to download something else? " yesno
case $yesno in
[Yy]* ) 'restart script code goes here';;
[Nn]* ) break;;
* ) echo "Try Again "
esac
done
If you design your shell script with shell functions, repeating a chunk of code gets much easier:
main() {
while true; do
next
if ! validate_opt 'Do you want to download something else?'; then
break
fi
done
}
validate_opt() {
local PS3="$1 (Press ctrl-c to exit) "
local choice
select choice in yes no; do
# This can be written more tersely,
# but for clarity...
case $choice in
yes) return 0;;
no) return 1;;
esac
done
}
do_download() {
echo
echo "Starting $build download for $opt1 from Jenkins"
echo
fetch "$1" # or whatever
}
next() {
if validate_opt 'Is this correct?'; then
do_download "$opt"
else
echo "Let's start over"
fi
}
main
function stage1 {
while true;do
read -p "Is this correct? (yes/no/abort) " yno
case $yno in
[Yy]*) stage2;;
[Nn]*) continue;;
[Aa]*) exit 0;;
*) echo "Try again";;
esac
done
}
function stage2 {
echo
echo "Starting $build download for $opt1 from Jenkins"
echo
while true;do
read -p "Do you want to download something else? " yesno
case $yesno in
[Yy]* ) stage1;;
[Nn]* ) exit 0;;
* ) echo "Try Again ";;
esac
done
}
stage1
You can do this using functions
The first function is stage 1 and the second stage2
After listing all the functions, at the bottom of the file we call stage1.
when the function stage1 executes and $yno= Y* or y* , it will skip to the stage2 function, vice versa when we in stage2

Infinite loop on yes/no ksh

I have an annoying issue that seems to cause and infinite loop and I can't work out why. If I call the following function, it keeps repeating the yes/no options infinitely down the screen until I crash out.
AuditUpload() {
clear
echo "Audit report generated successfully"
echo " "
echo "Do you wish to upload qhub_audit.csv? (1 = Yes/2 = No):"
sleep 1
select yn in "Yes" "No"; do
case $yn in
Yes ) AuditUploader; Auditvi; exit;;
No ) echo "Upload cancelled"; Auditvi; exit;;
esac
done
}
I put the sleep in to see if it would remedy the issue but it still does the same. This issue seems to be very intermittent and doesn't happen every time. This script is written in korn shell (ksh).
AuditUploader function:
AuditUploader() {
echo "Uploading qhub_audit.csv to $HOST..."
curl -v -T qhub_audit.csv -# ftp://xxxxxxxx:xxxxxxxxx#xxxxxxxxxxxxx.com/
if [ "$?" -ne "0" ]
then
echo "ERROR: Cannot upload qhubload.csv"
exit
else
clear
echo "qhub_audit.csv has been put on $HOST successfully"
tput cup 5 5
echo "Copy and paste this link into internet explorer to download:"
tput cup 7 5
echo "ftp://xxxxxxxx:xxxxxxxxx#xxxxxxxxxxxxx.com/qhub_audit.csv"
read LINK
fi
}
Auditvi function:
Auditvi() {
clear
echo "Do you wish to view qhub_audit.csv? (1 = Yes/2 = No):"
sleep 1
select yn in "Yes" "No"; do
case $yn in
Yes ) vi qhub_audit.csv; exit;;
No ) exit;;
esac
done
}
After a bit of playing around it looks like it was looping whenever the 'curl' command returned a specific error which stopped the kill $$ from working properly. I replaced kill $$ with exit 1 and amended the other functions accordingly. I also put in a contingency to use kermit in case the FTP failed. Anyway, this is what my code looks like now:
#########################################
# Upload quotehub audit report function #
#########################################
AuditUploader() {
echo "Uploading qhub_audit.csv to $HOST..."
curl -v -T qhub_audit.csv -# ftp://$USER:$PASSWD#$HOST/ -m 10
if [ "$?" -ne "0" ]
then
echo "ERROR: Cannot upload qhubload.csv via FTP"
if [ ${term} = "tty1A" ]
then
echo "Attempting to download to modems server..."
wermit -s qhub_audit.csv
if [ $? -ne 0 ]
then
echo "Cannot upload to modems either!"
echo "This file will have to be downloaded manually"
exit 1
else
clear
echo "qhub_audit.csv has been put on modems server successfully"
tput cup 5 5
echo "Copy and paste this link into START -> RUN to download:"
tput cup 7 5
echo "\\\\\\xxxxxxxx\download\general\qhub_audit.csv"
read LINK
fi
else
echo "Upload failed!"
exit 1
fi
else
clear
echo "qhub_audit.csv has been put on $HOST successfully"
tput cup 5 5
echo "Copy and paste this link into internet explorer to download:"
tput cup 7 5
echo "ftp://$USER:$PASSWD#$HOST/qhub_audit.csv"
read LINK
fi
}
#######################################################
# Function to prompt user to upload qhub audit report #
#######################################################
AuditUpload() {
clear
echo "Audit report generated successfully"
echo ""
echo "Do you wish to upload qhub_audit.csv? (y/n):"
read REPLY
case "$REPLY" in
Y) AuditUploader; Auditvi; exit;;
y) AuditUploader; Auditvi; exit;;
N) Auditvi; exit;;
n) Auditvi; exit;;
*) echo "invalid option";;
esac
}
######################################
# Function to view qhub audit report #
######################################
Auditvi() {
if [ "$?" -ne "0" ]
then
exit 1
else
clear
echo "Do you wish to view qhub_audit.csv? (y/n):"
read REPLY
case "$REPLY" in
Y) vi qhub_audit.csv; exit;;
y) vi qhub_audit.csv; exit;;
N) exit;;
n) exit;;
*) echo "invalid option"; Pause; Auditvi;;
esac
fi
}
Thanks again guys for all your help.

Resources