Shell Script with If, Select and Case - bash

Can anyone advise how to edit this script to perform the following:
If folder exists - "then are you sure you want to uninstall?"
If yes - perform file copying, if not then stop script.
Else - can't find folder, stop script.
if [ -e "/tmp/installpackage" ]
then
echo "Are you sure you want to uninstall?"
select yn in "Yes" "No"; do
case $yn in
Yes )
echo "Beginning uninstall...";
cp file1.txt original/path/location;
break;;
No )
echo "Stopping uninstall.";
exit 1;;
esac
done
else
echo "Can't find the folder, package not isntalled."
exit 1
fi

Your code works as expected. But you have to enter 1 or 2 and not yes or no.
However I would change the first line to:
if [ -d "/tmp/installpackage" ]
-d tests whether the file exists and is a directory

I think after the line esac you want a exit otherwise you have a infinite loop to ask you for answers

try
if [ -d "/tmp/installpackage" ]
then
echo "Are you sure you want to uninstall?"
select yn in "Yes" "No"; do
case $REPLY in
Yes )
echo "Beginning uninstall...";
cp file1.txt original/path/location;
break;;
No )
echo "Stopping uninstall.";
exit 1;;
*)
echo "Incorrect choice";
break;;
esac
done
else
echo "Can't find the folder, package not installed."
exit 1
fi

I would try testing for bail out conditions first then fall through to the uninstall code:
[ ! -d '/tmp/installpackage' ] && \
echo "Can't find the folder, package not isntalled." && exit 1
echo -n 'Are you sure you want to uninstall? [y|n] '
read answer
[[ ! "$answer" = [Yy] ]] && echo 'Stopping uninstall.' && exit 1
echo 'Beginning uninstall...'
cp file1.txt original/path/location

Related

How do I revert in case of wrong option?

select_again_dir:
echo -e "\033[32m enter the name of the source file; \033[0m"
echo
ls
echo
read build_source_dir
if [ ! -d $build_source_dir ]
then
echo "Folder Not Found. Please select again;"
goto select_again_dir:
else
echo "folder exists"
fi
Hello,
If the source file cannot be found, I want it to re-enter a value.
Is there a function you can suggest instead of goto?
The standard way is a while loop. One way to avoid duplication of the input read:
echo -e "\033[32m enter the name of the source file; \033[0m"
while [ ! -d "$build_source_dir" ]; do
echo
ls
echo
read build_source_dir
echo "Folder Not Found. Please select again: "
done
echo "folder exists"
Just loop it. You can use break and continue to your favor.
while true; do
echo -e "\033[32m enter the name of the source file; \033[0m"
echo
ls
echo
read build_source_dir
if [ ! -d "$build_source_dir" ]
then
echo "Folder Not Found. Please select again;"
continue # not really needed, there is nothing below to happen
else
echo "folder exists"
break # jump out of the loop
fi
done

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.

unexpected fi in bash script

This is the script and I keep getting an unexpected fi error. What am I missing? .. (I started using [] for the if statement but since I'm using this command I deleted the [] .. Is it ok this way?)
if type "java" 2>&1;
then
echo "All ok . . . ";
exit
else
read -n1 -r -p "Yo need to install"
while true; do
echo "Want to install??"
select yn in "y" "n"; do
case $yn in
y ) echo "Installing here..."; break;;
n ) echo "Ok... stopping..."; exit;;
esac
done
exit
fi
thanks!
while ends with done, not exit. Try this:
if type "java" 2>&1;
then
echo "All ok . . . ";
exit
else
read -n1 -r -p "Yo need to install"
while true; do
echo "Want to install??"
select yn in "y" "n"; do
case $yn in
y ) echo "Installing here..."; break;;
n ) echo "Ok... stopping..."; exit;;
esac # <-- ending `case`
done # <-- ending `select`
done # <-- while ends with `done`, not `exit`!
fi # <-- ending `if`
You have an exit before the last fi; I suppose that should be a done.

Shell script that asks user to continue with a y/n

I have a shell script that I want to ask the user if they want to continue. If they type 'n' and press enter the script will exit.
If they press 'y' and enter it will continue to run. I have this at the top of my script but it continues regardless of what I type.
What am I doing wrong ?
goon=
while [ -z $goon ]
do
echo -n 'Do you want to continue? '
read goon
if [[ $goon = 'n' ]]
then
break
fi
goon=
done
Use an infinity loop and case/esac like this:
while true
do
read -r -p 'Do you want to continue? ' choice
case "$choice" in
n|N) break;;
y|Y) echo 'Do your stuff here';;
*) echo 'Response not valid';;
esac
done
The 'break' statement will exit you out of your while loop.
If you want to exit the script you want to use 'exit'.
That works perfectly well for me if I get rid of the doubled square brackets:
if [ $goon = 'n' ]
Rather than echo + read, just use read -p
read -p "Do you want to continue? " goon
Here's a working example (== instead of = for equality testing)
goon=
while [ -z $goon ]
do
echo -n 'Do you want to continue? '
read goon
if [[ $goon == 'n' ]]
then
break
fi
goon=
done
Strange thing, the original works ok for me too ...
I'm less than positive, but it looks as though your if statement will always evaluate to false.
Here's a resource on BASH coding that explains how to use conditionals in the way you are attempting to.
http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-6.html#ss6.4
I think you mean "exit" instead of "break", if you want the whole script to exit.
Also, you aren't actually checking for "y", so it loops forever even if they do say "y".
if [[ $goon = 'n' ]]
then
exit
fi
if [[ $goon = 'y' ]]
then
break
fi
Try below script
#!/bin/bash
pause ()
{
REPLY=X
while [ "$REPLY" == "X" ] || [ "$REPLY" != "n" ]
do
echo -e "\t\tPress 'n' to continue\t\t\tPress 'x' to quit"
read -n1 -s
case "$REPLY" in
"x") exit ;;
"X") echo "case sensitive!!" ;;
"n") clear ;;
"N") echo "case sensitive!!" ;;
* ) echo "Invalid Option" ;;
esac
done
}
pause
echo "Hi"
am sure this script will give you only two options to move around...

Resources