I am making a new Menu Driven Shell Script in linux, I have simplified my table to just hello and bye to make this simpler, below is my basic menu layout
# Menu Shell Script
#
echo ----------------
echo menu
echo ----------------
echo [1] hello
echo [2] bye
echo [3] exit
echo ----------------
Basically I have the menu, I have been playing around with a few things recently but cant seem to get anything working as I am new to this, I think then next line would be
`read -p "Please Select A Number: " menu_choice`
but I am not sure what to do with the variable and what not.
I was wondering if anyone could help me with the next bit of code to simply get it to say hello when I press one, bye when 2 is pressed and exit when 3 when the user presses 3. It would be so much appreciated as I have been trying different ways for days and can't seem to get it to work.
you don't need those backticks for echo... and read
echo "----------------"
echo " menu"
echo "----------------"
echo "[1] hello"
echo "[2] bye"
echo "[3] exit"
echo "----------------"
read -p "Please Select A Number: " mc
if [[ "$mc" == "1" ]]; then
echo "hello"
elif [[ "$mc" == "2" ]]; then
echo "bye"
else
echo "exit"
fi
Edit
showMenu(){
echo "----------------"
echo " menu"
echo "----------------"
echo "[1] hello"
echo "[2] bye"
echo "[3] exit"
echo "----------------"
read -p "Please Select A Number: " mc
return $mc
}
while [[ "$m" != "3" ]]
do
if [[ "$m" == "1" ]]; then
echo "hello"
elif [[ "$m" == "2" ]]; then
echo "bye"
fi
showMenu
m=$?
done
exit 0;
Here is a sample
if [ $menu_choice -eq 1 ]
then
echo hello
elif [ $menu_choice -eq 2 ]
then
echo bye
elif [ $menu_choice -eq 3 ]
then
exit 0
fi
or using case
case $menu_choice in
1) echo hello
;;
2) echo bye
;;
3) exit 0
;;
esac
Related
I commented the things I have problem.
and also, is there any other way I can exit my loop without using the exit command?.................
#!/bin/bash
while [ "$done" != "true" ] #this don't work
do
echo "Please enter one of the following options"
echo "1. Move empty files"
echo "2. Check file size"
echo "3. Which file is newer"
echo "4. File check rwx"
echo "5. Exit".
echo -n "Enter Choice: "
read scale # starting from this part for checking if user only inputs numbers 1-5 not working
if ! [[ "$scale" =~ ^[0-6]+$ ]]
then
echo "Invalid Input"
fi #up to this part is not working
read -r answer
case "$answer" in
1) ./move_empty
exit 55
;;
2) ./file_size
exit 0
;;
3) ;;
;;
4)
;;
5) done="true";;
esac
done
There are few things Which should be avoided
while [ "$done" != "true" ] --> while [ $done -ne 1 ] /* -ne is not equal to */
case "$answer" in --> case $answer in
Complete Code
var=0
flag=1
while [ $var -ne 1 ]
do
echo "Please enter one of the following options"
echo "1. Move empty files"
echo "2. Check file size"
echo "3. Which file is newer"
echo "4. File check rwx"
echo "5. Exit".
echo -n "Enter Choice: "
read scale
if [ $scale -gt 0 -a $scale -lt 6 ]
then
echo "valid Input, you can procees for switch "
else
echo "invalid input.. go again & give correct one "
flag=0
fi
if [ $flag -eq 1 ]
then
read -r answer
case $answer in
1) ./move_empty
#exit 55
break
;;
2) ./file_size
#exit 0
break
;;
3)
exit 0
;;
4)
;;
5) done="true";;
esac
fi
done
To come out from loop, without using exit command, use break. Here is the answer from man 1 bash
break [n]
Exit from within a for, while, until, or select loop.
If n is specified, break n levels. n must be ≥ 1. If n
is greater than the number of enclosing loops, all
enclosing loops are exited. The return value is 0
unless n is not greater than or equal to 1.
#!/bin/bash
helpFunc()
{
echo "Usage:
$0 --arg1
$0 --arg2 filename add/delete/replace "hi how are you"
$0 --help
"
}
function fileread() {
pwd
echo "Fileread Function"
if [ -f $filename ]
then
echo "file exists"
filename=$1
cat $1
case "$1" in
add|ADD)
read $1
if [$2 == 'add' ]
then
echo $3 >> $1
echo "add opeartion completed"
fi
shift
;;
delete|DELETE)
read $1
echo "echo delet string from file"
if [$2 == 'delete' ]
then
sed '/$3/d' $1
echo "add opeartion completed"
fi
shift
;;
replace|REPLACE)
read $1
if [ $4 == 'replace' ]
then
sed "s/$5/$6/g" "$1" > temp.txt
else
echo "Error: Cannot read $1"
fi
shift
;;
esac
shift
# return 0
else
echo "file not exist"
#return 1
fi
}
while [ $# ]
do
case "$1" in
--a)
if [ -z "$2" ]
then
echo "No argument supplied"
echo "hello" && echo " current process id : $$ "
else
echo -e "no need of sending arguments for --a"
helpFunc a;
exit 1
shift
fi
;;
--b)
if [ $( echo -e $2 | grep -c -E "^-" ) -eq 0 ]
then
fileName=$2
if [ -f "$fileName" ]
then
echo -e "The file is valid"
echo "Displaying $2 file..."
[ -z $fileName ] && { echo "File name missing"; exit 1; } || cat $fileName
case "$filename" in
add|ADD)
echo "adding"
fileread $3 $4
shift
;;
delete|DELETE)
echo "echo deleting"
fileread
shift
;;
replace|REPLACE)
echo "replacing"
fileread
shift
;;
esac
else
echo -e "please enter the valid file name or location"
helpFunc b;
exit 1
shift
fi
fi
esac
shift
done
exit 0
function file read should ignore the case inputs like ADD/add , delete/Delete etc.. and perform operations if i give the cmd line arguments and values and it should validate case sensitivity, file existence and path of the file
./script.sh -a -b /etc/opt/test.txt ADD "hi how are you" delete "i am fine" REPLACE "hi " "hey"
I want to create a select menu in it, like this:
echo "Choose your option:"
1) Factorial Calculation
2) Addition Calculator
3) Quit
And I have some shell scripts;
Factorial
./fact.sh
#!/bin/bash
fact=1
#taking input from user
echo -e "enter a number"
read n
#if enter value less than 0
if [ $n -le 0 ] ; then
echo "invalid number"
exit
fi
#factorial logic
if [ $n -gt 0 ] ; then
for((i=$n;i>=1;i--))
do
fact=`expr $fact \* $i`
done
fi
echo "The factorial of $n is $fact"
Addition
./add.sh
#!/bin/bash
#function to add two numbers
add()
{
x=$1
y=$2
echo -e "Number entered by u are: $x and $y"
echo "sum of $1 and $2 is `expr $x + $y` "
}
# main script
echo "enter first number"
read first
echo "enter second number"
read sec
#calling function
add $first $sec
echo "end of the script"
I have to create a menu, how should I proceed?
You can use select.
For your example:
select option in Factorial Addition Quit; do
case "$option" in
"Factorial")
echo "Factorial"
break ;;
"Addition")
echo "Addition"
break ;;
"Quit") exit ;;
esac
done
A shell script should take multiple condition in single line input and it should take one end of input character to perform next operation. ie.
#!/bin/bash
#Functions are defined here 1 2 3 4 5
echo "choice"
echo
echo "[1] one"
echo "[2] two"
echo "[3] three"
echo "[4] four"
echo "[5] five"
echo
read -p "Enter choice: " ch
if [ "$ch" = "1" ]; then
function_1
else
if [ "$ch" = "2" ]; then
function_2
else
if [ "$ch" = "3" ]; then
function_3
else
if [ "$ch" = "4" ]; then
function_4
else
if [ "$ch" = "5" ]; then
function_5
fi
fi
fi
fi
fi
now say end of input taking denoted by 'e' hence if I execute the .sh file and in "Enter choice"
$Enter choice: 1 3 5 e
it should execute 1 3 and 5th function one by one
how to do that?
You can iterate over all the choices until you find the 'end of input':
read -p "Enter choice: " ch
for choice in $ch; do
[ "$choice" == 'e' ] && break
eval function_$choice
done
NOTE: eval will assemble a command from the arguments and then execute it through the shell
You should iterate over your string ch until "e" appears:
#!/bin/bash
#Functions are defined here 1 2 3 4 5
echo "choice"
echo
echo "[1] one"
echo "[2] two"
echo "[3] three"
echo "[4] four"
echo "[5] five"
echo
read -p "Enter choice: " ch
for i in ${ch}
do
if [ "$i" == "1" ]; then
function_1
else if [ "$i" == "2" ]; then
function_2
else if [ "$i" == "3" ]; then
function_3
else if [ "$i" == "4" ]; then
function_4
else if [ "$i" == "5" ]; then
function_5
else if [ "$i" == "e" ]; then
break
fi
fi
fi
fi
fi
fi
but the answer of mxlian is "cleaner". i just corrent your code..
It would be better if you made each input parameter an option and used getopts ie
myProg.sh -a aArg -b bArg -c cArg
Inside myProg.sh:
while getopts "a:b:c" option
do
case $option in
a) function_1;;
b) function_2;;
c) function_3;;
*) exitFunc "Incorrect argument";; # You need to write exitFunc()
esac
done
This way you can have a missing option ie only option a and c (no b). If you do it your way and one parameter is missing (or null) say paramater 3 then parameter 4 becomes parameter 3 etc.
I keep getting unexpected End of file error while running a if else statement
#! /bin/bash
echo -e "1: Proband\n 2: mincount\n Enter an option:"
read promin
echo $promin
if ($promin == 1) then
echo -e "Enter the proband file name\n"
read proband_file
echo "$proband_file"
endif
if ($promin == 2) then
echo -e "enter the min count number\n"
read mincount
echo "$mincount mincount"
endif
I tried fi instead of elseif too. But i still get the same error. Can someone help me fix that?
This is how you write an if-statement in bash:
if - then - fi
if [ conditional expression ]
then
statement1
statement2
fi
if - then - else - fi
If [ conditional expression ]
then
statement1
statement2
else
statement3
statement4
fi
if - then - elif - else - fi
If [ conditional expression1 ]
then
statement1
statement2
elif [ conditional expression2 ]
then
statement3
statement4
else
statement5
fi
Example of a conditional expression:
#!/bin/bash
count=100
if [ $count -eq 100 ]
then
echo "Count is 100"
fi
IMPROVED
The if is syntax is not correct. In the if there should be a program (bash internal or external) run, which returns an exit code. If it is 0 then if is true, otherwise it is false. You can use grep or any other utility, like test or /usr/bin/[. But bash has a built-in test and [.
So [ "$var" -eq 1 ] returns 0 if $var equals 1, or return 1 if $var not equals 1.
In your case I would suggest to use case instead of if-then-elif-else-fi notation.
case $x in
1) something;;
2) other;;
*) echo "Error"; exit 1;;
easc
Or even use select. Example:
#!/bin/bash
PS3="Enter an option: "
select promin in "Proband" "mincount";do [ -n "$promin" ] && break; done
echo $promin
case "$promin" in
Proband) read -p "Enter the proband file name: " proband_file; echo "$proband_file";;
mincount) read -p "Enter the min count number: " mincount; echo "$mincount mincount";;
*) echo Error; exit 1;;
esac
This will print the "Enter an option: " prompt and wait until a proper answer is presented (1 or 2 or ^D - to finish the input).
1) Proband
2) mincount
Enter an option: _
Then it checks the answer in the case part. Meanwhile $promin contains the string, $REPLY contains the entered answer. It also can be used in case.
I just changed your code and I think it works now.
I think the problem is you should fi instead of endif...
#!/bin/sh
echo "1: Proband\n2: mincount\nEnter an option:"
read promin
echo $promin
if [ $promin -eq "1" ]
then
echo "Enter the proband file name\n"
read proband_file
echo "$proband_file"
elif [ $promin -eq "2" ]
then
echo "enter the min count number\n"
read mincount
echo "$mincount mincount"
fi
#! /bin/bash
echo -e "1: Proband\n2: mincount\nEnter an option:"
read promin
echo $promin
if (($promin == 1)); then
echo -e "Enter the proband file name\n"
read proband_file
echo "$proband_file"
elif (($promin == 2)); then
echo -e "Enter the min count number\n"
read mincount
echo "$mincount mincount"
fi
I don't know if you need an if-else statement or two if statemnts. The above has an if-else.
If you need two if statements, then insert a line of code below the "echo "$proband_file"" line with the text:
fi
Then replace the line "elif (($promin == 2)); then" with the following code:
if (($promin == 2)); then