Bash if blocking elif - bash

I am trying to write a calculator script but the first if blocks the elif. What I mean is when I try to run it I press 1 but it runs as if I pressed 2. Here is my code.
echo "For Advanced mode press 1"
echo "For Help press 2"
loop=1
while [ $loop=1 ]; do
read n
if [ $n=2 ]; then
echo "To use the calculator follow the promptings."
echo "If asked, the operators are: "
echo "* for multiplication, / for division."
echo "+ for addition, - for subtraction."
echo "% for modulus, which is division remainder"
echo "== is equal to, != is not equal to."
echo "** for exponents"
n=""
elif [ $n=1 ]; then
read a
break
fi
done
echo "_______________________"
echo "What would you like to do?"
echo "Press 1 for basic arith"
echo -n "Press 2 for geometry"
read choice
loop=2
if [ $choice=1]; then
while [ $loop=2 ]; do
echo -n "Enter X Value: "
read x
echo -n "Enter Operator: "
read op
echo -n "Enter Y Value: "
read y
ans=$((x $op y))
echo "$x $op $y = $ans"
echo "____________________"
echo "To input a new function, press enter"
read cont
done
fi

The [ built-in is used for evaluating conditions. There must be a space after the opening [ and a space before before the closing ], otherwise it's incorrect syntax.
Inside a [ ... ] expression, you can use various conditional operators. One such operator is =. You must put spaces before and after an operator, otherwise it's not recognized as an operator.
For example, [ $n=2 ] where the value of n is 1, will be evaluated as [ 1=2 ]. The 1=2 is not evaluated as a condition, because there are no spaces around it. The 1=2 will be evaluated as a string "1=2". And any non empty string in Bash is truthy, so the statement [ 1=2 ] yields true, even if it doesn't "look like" it would be true.
You must write [ "$n" = 2 ] so that = is interpreted as the conditional operator, and the expression doesn't become a single string. Note that spaces are extremely important in Bash. Spaces separate the logical elements of a program, without spaces expressions are concatenated as strings.
Also notice that I added double quotes around the variable. This is to protect the expression in case the variable is empty. If for example you write [ $n = 2 ] and the variable is empty, then the expression will be evaluated as [ = 2 ], which is a malformed expression, and the script will crash with an error.

Put spaces between your condition elements like $n = 2 not $n=2.You should pass it's arguments as whitespace separated words. So your code should be as following:
echo "For Advanced mode press 1"
echo "For Help press 2"
loop=1
while [ $loop = 1 ]; do
read n
if [ $n = 2 ]; then
echo "To use the calculator follow the promptings."
echo "If asked, the operators are: "
echo "* for multiplication, / for division."
echo "+ for addition, - for subtraction."
echo "% for modulus, which is division remainder"
echo "== is equal to, != is not equal to."
echo "** for exponents"
n=""
elif [ $n = 1 ]; then
read a
break
fi
done
echo "_______________________"
echo "What would you like to do?"
echo "Press 1 for basic arith"
echo -n "Press 2 for geometry"
read choice
loop=2
if [ $choice = 1 ]; then
while [ $loop = 2 ]; do
echo -n "Enter X Value: "
read x
echo -n "Enter Operator: "
read op
echo -n "Enter Y Value: "
read y
ans=$((x $op y))
echo "$x $op $y = $ans"
echo "____________________"
echo "To input a new function, press enter"
read cont
done
fi

Related

shell script * operation gives too many arguments

I m doing a simple calculator with option of choosing to continue or not . But when I try multiplying operation I get error in the console :
calculator.sh: line 17: [: too many arguments
calculator.sh: line 22: [: too many arguments
calculator.sh: line 27: [: too many arguments
calculator.sh: line 32: [: too many arguments
Which basically means all my operations has this error , but that is not true when I use them , they act normally .
I searched in stack overflow for similarities , but the examples are different . I escaped the * with slash , but I think it shouts the error in the comparing with the character "*" in order getting to the body of the if statement.
Here is the code:
#!/bin/bash
choice="Y"
while [ $choice == "Y" ]
do
echo -n "Enter first value:"
read firstvar
echo -n "Enter second value:"
read secondvar
echo -n "Enter last value:"
read compvar
echo -n "Enter operation:"
read ops
counter=0
result=0
while [ $result != $compvar ]
do
if [ $ops == "+" ]
then result=$((firstvar+secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ $ops == "-" ]
then result=$((firstvar-secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ $ops == "*" ]
then result=$((firstvar\*secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ $ops == "/" ]
then result=$((firstvar/secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
else
echo "Input valid operation !!!"
echo "Do you want to continue ? Y/N"
read choice
break
fi
counter=$((counter+1))
done
done
The problem is likely not because the "*" in script, but because of an asterisk in your $ops variable.
You should double-quote the variables to avoid globbing being applied to them; rewrite your tests like this:
elif [ "$ops" = "*" ]
Here's a very helpful resource for checking your shell scripts.
First, see the comment by Charles Duffy WRT "==" vs "=" for string tests.
Change occurrences of $ops to "${ops}".
Remove the escape in result=$((firstvar*secondvar)).
I took the liberty to reformat the script just a bit.
Hope this helps.
#!/bin/bash
choice="Y"
while [ $choice = "Y" ]
do
echo -n "Enter first value:"
read firstvar
echo -n "Enter second value:"
read secondvar
echo -n "Enter last value:"
read compvar
echo -n "Enter operation:"
read ops
counter=0
result=0
while [ $result != $compvar ]
do
if [ "${ops}" = "+" ]; then
result=$((firstvar+secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ "${ops}" = "-" ]; then
result=$((firstvar-secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ "${ops}" = "*" ]; then
result=$((firstvar*secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
elif [ "${ops}" = "/" ]; then
result=$((firstvar/secondvar))
echo "Do you want to continue ? Y/N"
read choice
break
else
echo "Input valid operation !!!"
echo "Do you want to continue ? Y/N"
read choice
break
fi
counter=$((counter+1))
done
done

if statement shell script error

Hello I don't know if this will be a duplicate , but I really don't see the error in this piece of code . It gives me an error at the then statement and I think there is no error .
I have putted comments on the two lines where the code breaks .
Here is the code:
#!/bin/bash
echo -n "Enter first value:"
read firstvar
echo -n "Enter second value:"
read secondvar
echo -n "Enter last value:"
read compvar
echo -n "Enter operation:"
read ops
counter=0
result=0
while [ $result -eq $compvar ]
do
if [ $ops -eq "+" ]
then result = $((firstvar+secondvar))
elif [ $ops -eq "-" ]
then result = $((firstvar-secondvar))
#elif[ $ops -eq "*" ]
#then result = $((firstvar\*secondvar))
#elif[ $ops -eq "/" ]
#then result = $((firstvar/secondvar))
else
echo "Input valid operation !!!"
fi
(($counter++))
done
Oh shoot , I m retarded . Missed the space between "elif" and the "[" .
You need to learn how to space and indent to have your code legible.
#!/bin/bash
echo -n "Enter first value:"; read firstvar
echo -n "Enter second value:"; read secondvar
echo -n "Enter last value:"; read compvar
echo -n "Enter operation:"; read ops
counter=0; result=0 #initialize variables
while [ $result -eq $compvar ]; do
if [ $ops = "+" ]; then
result = $((firstvar+secondvar))
elif [ $ops = "-" ]; then
result=$((firstvar-secondvar))
else
echo "Input valid operation !!!"
fi
((++counter))
done
Writing code is the same as writing literature. There are forms to use to make it easy for the reader (even if it's just you 6 months later) to follow. Your code above is confusing, and will bite you on the butt later. Add comments to.
The while loop is gratuitous and will do nothing-- the -eq should at least be -ne. The counter could be initialized as an integer to avoid problems that could arise, but it's also never used.

how to use if condition in linux

echo "Enter a grade"
read grade
if test $grade="A"
then
basic=6000
elif test $grade="B"
then
basic=5000
else
basic=4000
fi
echo "Your basic is $basic"
When I execute this code in terminal with any grade it always returns "Your basic is 6000". what is the mistake in this code?
You need to put a space around the =.
As it is now, you just give the test command one argument, which is $grade="A", since space separates arguments. If you put spaces around =, then test will have 3 arguments, i.e. (an expanded) $grade, = and "A".
Thus:
echo "Enter a grade"
read grade
if test $grade = "A"
then
basic=6000
elif test $grade = "B"
then
basic=5000
else
basic=4000
fi
echo "Your basic is $basic"
#!/bin/bash
echo "Enter a grade"
# Read single char
read -n 1 grade
echo $grade
if [ "$grade" == 'A' ]; then
basic=6000
elif [ "$grade" == 'B' ]; then
basic=5000
else
basic=4000
fi
echo "Your basic is $basic"

Creating a calculator script

I am trying to make a calculator with a bash script.
The user enters a number, chooses whether they wish to add, subtract, multiply or divide. Then the user enters a second number and is able to choose whether to do the sum, or add, subtract, multiply or divide again on a loop.
I cannot rack my head around this right now
echo Please enter a number
read number
echo What operation would you like to perform: 1: Add, 2: Subtract, 3: Multiple, 4: Divide
read operation
case $operation in
1) math='+';;
2) math='-';;
3) math='*';;
4) math='/';;
*) math='not an option, please select again';;
esac
echo "$number $math"
echo Please enter a number
read number2
echo What operation would you like to perform: 1: Add, 2: Subtract, 3: Multiple, 4: Divide, 5: Equals
read operation2
case $operation2 in
1)math2='Add';;
2)math2='Subtract';;
3)math2='Multiply';;
4)math2='Divide';;
5)math2='Equals';;
*)math2='not an option, please select again';;
esac
echo You have selected $math2
exit 0
This is what I have done so far, but can anyone help me work out how to loop back on the calculator?
The lesser-known shell builtin command select is handy for this kind of menu-driven program:
#!/bin/bash
while true; do
read -p "what's the first number? " n1
read -p "what's the second number? " n2
PS3="what's the operation? "
select ans in add subtract multiply divide; do
case $ans in
add) op='+' ; break ;;
subtract) op='-' ; break ;;
multiply) op='*' ; break ;;
divide) op='/' ; break ;;
*) echo "invalid response" ;;
esac
done
ans=$(echo "$n1 $op $n2" | bc -l)
printf "%s %s %s = %s\n\n" "$n1" "$op" "$n2" "$ans"
done
Sample output
what's the first number? 5
what's the second number? 4
1) add
2) subtract
3) multiply
4) divide
what's the operation? /
invalid response
what's the operation? 4
5 / 4 = 1.25000000000000000000
If I was going to get fancy with bash v4 features and DRY:
#!/bin/bash
PS3="what's the operation? "
declare -A op=([add]='+' [subtract]='-' [multiply]='*' [divide]='/')
while true; do
read -p "what's the first number? " n1
read -p "what's the second number? " n2
select ans in "${!op[#]}"; do
for key in "${!op[#]}"; do
[[ $REPLY == $key ]] && ans=$REPLY
[[ $ans == $key ]] && break 2
done
echo "invalid response"
done
formula="$n1 ${op[$ans]} $n2"
printf "%s = %s\n\n" "$formula" "$(bc -l <<< "$formula")"
done
Wrapping Code in a Loop
If you just want to wrap your code in a Bash looping construct, and are willing to hit CTRL-C to terminate the loop rather than do something more fancy, then you can wrap your code in a while-loop. For example:
while true; do
: # Your code goes here, inside the loop.
done
Just make sure to move your unconditional exit statement out of the body of the loop. Otherwise, the loop will terminate whenever it reaches that line.
For your ~/.bashrc:
alias bc="BC_ENV_ARGS=<(echo "scale=2") \bc"
Just use bc, with that alias it automatically works with two decimals instead of integers.
!/bin/bash
PS3="what's the operation? "
declare -A op=([add]='+' [subtract]='-' [multiply]='*' [divide]='/')
while true; do
read -p "what's the first number? " n1
read -p "what's the second number? " n2
select ans in "${!op[#]}"; do
for key in "${!op[#]}"; do
[[ $REPLY == $key ]] && ans=$REPLY
[[ $ans == $key ]] && break 2
done
echo "invalid response"
done
formula="$n1 ${op[$ans]} $n2"
printf "%s = %s\n\n" "$formula" "$(bc -l <<< "$formula")"
done
Please use the following script.
clear
sum=0
i="y"
echo " Enter one no."
read n1
echo "Enter second no."
read n2
while [ $i = "y" ]
do
echo "1.Addition"
echo "2.Subtraction"
echo "3.Multiplication"
echo "4.Division"
echo "Enter your choice"
read ch
case $ch in
1)sum=`expr $n1 + $n2`
echo "Sum ="$sum;;
2)sum=`expr $n1 - $n2`
echo "Sub = "$sum;;
3)sum=`expr $n1 \* $n2`
echo "Mul = "$sum;;
4)sum=`expr $n1 / $n2`
echo "Div = "$sum;;
*)echo "Invalid choice";;
esac
echo "Do u want to continue ?"
read i
if [ $i != "y" ]
then
exit
fi
done
#calculator
while (true) # while loop 1
do
echo "enter first no"
read fno
if [ $fno -eq $fno 2>/dev/null ]; # if cond 1 -> checking integer or not
then
c=1
else
echo "please enter an integer"
c=0
fi # end of if 1
if [ $c -eq 1 ]; #if 2
then
break
fi # end of if 2
done # end of whie 1
while(true) #while loop 2
do
echo "enter second no"
read sno
if [ $sno -eq $sno >/dev/null 2>&1 ] # if cond 3 -> checking integer or not
then
c=1
else
echo "please enter an integer"
c=0
fi # end of if 3
if [ $c -eq 1 ] # if cond 4
then
break
fi # end of if 4
done #2
while(true) # while loop 3
do
printf "enter the operation (add,div,mul,sub) of $fno and $sno\n"
read op
count=0
##addition
if [ $op = add ] #if cond 5
then
echo "$fno+$sno is `expr $fno + $sno`"
#multiplication
elif [ $op = mul ];
then
echo "$fno*$sno is `expr $fno \* $sno`"
#substraction
elif [ $op = sub ]
then
while(true) #while loop 3.1
do
printf "what do you want to do??? \n 1. $fno-$sno \n 2. $sno-$fno"
printf "\n press the option you want to perform?(1 or 2)\n"
read opt
if [ $opt = 1 ] #if cond 5.1
then
echo "$fno-$sno is `expr $fno - $sno`"
break
elif [ $opt = 2 ]
then
echo " $sno-$fno is `expr $sno - $fno`"
break
else "please enter valid options to proceed(1 or 2)";
clear
fi #end of if 5.1
done # end of 3.1
#division
elif [ $op = div ]
then
while(true) # whilw loop 3.2
do
printf "what do you want to do??? \n 1. $fno/$sno \n 2. $sno/$fno"
printf "\n press the option you want to perform?(1 or 2)\n"
read opt
if [ $opt = 1 ] #if cond 5.2
then
echo "$fno divided by $sno is `expr $fno / $sno`"
break
elif [ $opt = 2 ]
then
echo " $sno divided by $fno is `expr $sno / $fno`"
break
else
clear
fi #end of if 5.2
done # end of 3.2
else
echo "valid option please!!!"
count=1
fi # end of if 5
if [ $count -eq 0 ] #if cond 6
then
echo "Do you want to do more ops"
echo "(y/n)"
read ans
clear
if [ $ans = n ] # if 6.1
then
break
fi # end of if 6.1
fi #end of if 6
done #end of while 3

How to if/else statement in shell script

I'm receiveing an error on a simple script when using if/else statement.
The code:
#!/bin/sh
count=100
if [$count > 3]; then
echo "Test IF"
fi
The error: /bin/ash: line 6: [100: not found
#!/bin/sh
count=100;
if [ "$count" -gt 3 ]; then
echo "Test IF";
fi
Correct your syntax: spaces must be used around [ and ], parameter expansions must be quoted, and -gt is appropriate for numeric comparisons inside of [ ]. > in sh is used as redirection operator; if you want to use it in arithmetical comparison, you must use the bash-only syntax
$(( $count > 3 ))
#!/bin/sh
if [ $var -eq 12 ]; then
echo "This is a numeric comparison if example"
fi
if [ "$var" = "12" ]; then
echo "This is a string if comparison example"
fi
if [[ "$var" = *12* ]]; then
echo "This is a string regular expression if comparison example"
fi
The if statement in shell uses the command [.
Since [ is a command (you could also use 'test'), it requires a space before writing the condition to test.
To see the list of conditions, type:
man test
You'll see in the man page that:
s1 > s2 tests if string s1 is after string s2
n1 gt n2 tests if integer n1 is greater than n2
In your case, using > would work, because string 100 comes after string 3, but it is more logical to write
if [ $count -gt 3 ]; then
echo "test if"
fi
this will also do!
#!/bin/sh
count=100
if [ $count -gt 3 ];
then
echo "Test IF"
fi
if [[ "$x" == "true" ]]; then
echo "value matched"
else
echo "value doesn't matched"
fi

Resources