Shell script to take multiple user input in single file - linux

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.

Related

How to Control Number of Parameters Entered into Function

I am trying to make a simple menu-driven calculator script. I am trying to make it such that after selecting A (add) or B (subtract) from the menu, it'll call the function and display the corresponding message when:
The parameters entered when function called is greater than 3
No parameters are entered when the function is called
The operator entered when the function is called is neither "+" or "-"
Right now it is doing the parameter check when I call the script ./mycalc.sh
executing the script
Am not sure how to make it check parameters after the function is called?
#!/bin/bash
display() {
echo "Calculator Menu"
echo "Please select an option between add, subtract or exit"
echo "A. Add"
echo "B. Subtract"
echo "C. Exit"
}
#initialize choice n
choice=n
if [[ $# -ne 3 ]]
then echo " You have not entered 3 parameters"
exit 1
fi
if [ $# -eq 0 ]
then
echo " You have not entered any parameters, please input 3. "
fi
if [[ $2 != [+-] ]]
then
echo " Please enter an add or subtract operator."
exit 1
fi
add() {
echo " The sum of $one + $three equals $(( $one $op $three ))"
}
subtract () {
echo " The difference of $one - $three equals $(( $one $op $three )) "
}
while [ $choice != 'C' ]
do display
read choice
if [ $choice = 'A' ]
then
read -p "Please enter two operands and the operator '+': " one op three
add $one $op $three
elif [ $choice = 'B' ]
then
read -p " Please enter two operands and the operator '-': " one op three
subtract $one $op $three
elif [ $choice = 'C' ]
then
echo "Thank you for using this program. The program will now exit."
fi
done
sleep 3
exit 0
if [ $# > 3 ]
then
echo " You need to input 3 parameters. "
fi
Within [...], the > is simply redirection. You'll find an empty file named 3 in your current directory.
Since this is an error condition for your script, you'll want to exit:
if [[ $# -ne 3 ]]; then
echo "usage: $0 operand1 operator operand2" >&2
exit 1
fi
And to test the operator, there are many ways.
case, but it's a bit verbose
case $2 in
'+'|'-') : ;;
*) echo "Operator must be + or -" >&2
exit 1
;;
esac
Within [[...]] the == and != operators are pattern matching operators
if [[ $2 != [+-] ]]; then
echo "Operator must be + or -" >&2
exit 1
fi

a=( one two three ) -- why does for x in $a only loop over "one"?

I have this script:
#!/bin/bash
if [ -z "$1" ]; then
echo "usage: ./test.sh [one|two|three|four|five]"
exit
elif [ $# -eq 1 -a $1 = "all" ]; then
params=("one" "two" "three" "four" "five")
else
params=$#
fi
echo "=========="
for param in $params
do
if [ $param = "one" ]; then
echo "one"
elif [ $param = "two" ]; then
echo "two"
elif [ $param = "three" ]; then
echo "three"
elif [ $param = "four" ]; then
echo "four"
elif [ $param = "five" ]; then
echo "five"
fi
echo "=========="
done
if I try ./test.sh one or ./test.sh two ecc it work, but when I try ./test.sh allit not work and print only one.
Where is the problem???
Thanks
Dario
for param in $params
...is the wrong way to expand an array. Instead, use:
params=( "$#" )
for param in "${params[#]}"
To explain why array syntax is better, consider the following:
params=( "first item" "second item" "third item" )
for param in "${params[#]}"; do
echo "$param"
done
...you can't do that (keeping your words together) with the string syntax.
Rather than storing your args in $params, store all values in args, for example:
elif [ $# -eq 1 ] && [ "$1" = all ]; then
set -- one two three four five
# ^ this modifies argv ($#)
fi
Then, you don't have to use bash arrays, you can simply iterate with:
for param in "$#"; do
Often, bash-only features are used (called bashisms), while they may be unnecessary and less portable.
Another thing, replace the big ifelse with a case:
case "$param" in
one)
echo one
;; # equivalent of "break"
two)
echo two
;;
*)
echo default case
;;
esac

Bash - While Loop

I am having trouble with this while loop. Here is the error I am getting currently : [: : unary operator expected (on line 3)
Here is my code:
#!/bin/bash
while [ "$option" <= 3 ]; do
echo "1) View 'HelloWorld' Text";
echo "2) View 'MyName' Text";
echo "3) View 'HappyFall' Text";
echo "4) Exit\n";
read -p "Please choose your option using numbers 1-4: " option;
if [ "$option" == 1 ]
then
cat HelloWorld
elif [ "$option" == 2 ]
then
cat MyName
elif [ "$option" == 3 ]
then
cat HappyFall
else
echo "Exiting...";
fi
done
<= is not a valid comparison in bash scripting, but -le (less than or equal) is.
There are two different types of comparison in scripting: those for strings, and those for numbers.
Stings typically use == or != for equal or not equal.
Integers, however, use:
-eq equal
-ne not equal
-lt less than
-le less than or equal
-gt greater than
-ge greater than or equal
Here's a more comprehensive list:
http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29
Error aside, this is a good use case for the select command:
options=(
"View 'HelloWorld' Text"
"View 'MyName' Text"
"View 'HappyFall' Text"
"Exit"
)
select option in "${options[#]}"; do
case $REPLY in
1) cat HelloWorld ;;
2) cat MyName ;;
3) cat HappyFall ;;
*) break ;;
esac
done

unexpected End of File error in if else statement

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

Shell Script for Menu

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

Resources