Comparing numbers using Bash - bash

I wrote a script to compare two numbers:
#!/bin/bash
read X
read Y
if [[ $X -le $Y ]];
then
echo "X is less than Y"
elif [[ $X -ge $Y ]];
then
echo "X is greater than Y"
else
echo "X is equal to Y"
fi
For some reason when the value of X and Y are the same, the else condition is not executed. Instead the if [[ $X -le $Y ]]; is executed.
When I change the position of the if and else conditions:
#!/bin/bash
read X
read Y
if [[ $X -eq $Y ]];
then
echo "X is equal to Y"
elif [[ $X -ge $Y ]];
then
echo "X is greater than Y"
else
echo "X is less than Y"
fi
The else condition is executed for this case. Can someone please give me an explanation to why the else condition is executed for one case but not the other?

-le and -ge are like <= and >=.
-le = less than or equal
-ge = greater than or equal
-lt = less than
-gt = greater than
It'll work if you switch to -lt and -gt:
if [[ $X -lt $Y ]]
then
echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
echo "X is greater than Y"
else
echo "X is equal to Y"
fi
You can also use (( )) for arithmetic operations. It has more natural syntax: you can use < and >, you don't need spaces around the operators, and $ dollar signs are optional.
if ((X < Y))
then
echo "X is less than Y"
elif ((X > Y))
then
echo "X is greater than Y"
else
echo "X is equal to Y"
fi

Related

Bash Syntax Error in conditional statement

I am trying to code a script that will tell the user if a triangle is isosceles, equilateral, or scalene. The error is occuring in line 7 (The elif line)
#!/bin/bash
read -p "Enter a number: " x
read -p "Enter a number: " y
read -p "Enter a number: " z
let "a = x + y + z"
if [ $x -eq $y ] && [ $y -eq $z ]
then echo "EQUILATERAL"
elif [[[ $x -eq $y ] && [ $y != $z ]] || [[ $x -eq $z ] && [ $z != $y ]] || [[ $y -eq $z ] && [ $z != $x ]]]
then echo "ISOSCELES"
elif [ $a -gt 1000 ]
then echo "Cannot equal more than 1000"
fi
I do realize that I could do the same thing with multiple elif lines, but I also have another elif as well and I want to keep it clean. Thanks all!
It seems like you think square brackets in the shell are like parentheses in C-style programming languages. That's not how they work. [ is a synonym for the test command, the condition it introduces ends with ]. And [[ is a special token that introduces a conditional expression, which ends with ]]. You can't mix them up, you can't add additional brackets like [[[, and they don't nest.
The grouping operators in the shell are { ... } and ( ... ); the latter also creates a subshell.
elif ( [[ $x -eq $y ]] && [[ $y != $z ]] ) || ( [[ $x -eq $z ]] && [[ $z != $y ]] ) || ( [[ $y -eq $z ]] && [[ $z != $x ]] )

Check if a function return is in an interval [duplicate]

I want to just insert number between two values, and otherwise the script repeated until correct number.
This is my script and it does not work correctly:
validation(){
read number
if [ $number -ge 2 && $number -ls 5 ]; then
echo "valid number"
break
else
echo "not valid number, try again"
fi
}
echo "insert number"
validation
echo "your number is" $number
If you are using Bash, you are better off using the arithmetic expression, ((...)) for readability and flexibility:
if ((number >= 2 && number <= 5)); then
# your code
fi
To read in a loop until a valid number is entered:
#!/bin/bash
while :; do
read -p "Enter a number between 2 and 5: " number
[[ $number =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
if ((number >= 2 && number <= 5)); then
echo "valid number"
break
else
echo "number out of range, try again"
fi
done
((number >= 2 && number <= 5)) can also be written as ((2 <= number <= 5)).
See also:
Test whether string is a valid integer
How to use double or single brackets, parentheses, curly braces
Your if statement:
if [ $number -ge 2 && $number -ls 5 ]; then
should be:
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
Changes made:
Quoting variables is considered good practice.
ls is not a valid comparison operator, use le.
Separate single-bracket conditional expressions with &&.
Also you need a shebang in the first line of your script: #!/usr/bin/env bash
if [ $number -ge 2 && $number -ls 5 ]; then
should be
if [[ $number -ge 2 && $number -le 5 ]]; then
see help [[ for details
Try bellow code
echo "Enter number"
read input
if [[ $input ]] && [ $input -eq $input 2>/dev/null ]
then
if ((input >= 1 && input <= 4)); then
echo "Access Granted..."
break
else
echo "Wrong code"
fi
else
echo "$input is not an integer or not defined"
fi
2 changes needed.
Suggested by Sergio.
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
There is no need of break. only meaningful in a for, while, or until loop
while :; do
read option
if [[ $option -ge 1 && $option -lt 4 ]]; then
echo "correct"
c
break
else
echo "Incorrect option selected,choose an option between [1-4]"
fi
done

How to check if a number is within a range in shell

I want to just insert number between two values, and otherwise the script repeated until correct number.
This is my script and it does not work correctly:
validation(){
read number
if [ $number -ge 2 && $number -ls 5 ]; then
echo "valid number"
break
else
echo "not valid number, try again"
fi
}
echo "insert number"
validation
echo "your number is" $number
If you are using Bash, you are better off using the arithmetic expression, ((...)) for readability and flexibility:
if ((number >= 2 && number <= 5)); then
# your code
fi
To read in a loop until a valid number is entered:
#!/bin/bash
while :; do
read -p "Enter a number between 2 and 5: " number
[[ $number =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
if ((number >= 2 && number <= 5)); then
echo "valid number"
break
else
echo "number out of range, try again"
fi
done
((number >= 2 && number <= 5)) can also be written as ((2 <= number <= 5)).
See also:
Test whether string is a valid integer
How to use double or single brackets, parentheses, curly braces
Your if statement:
if [ $number -ge 2 && $number -ls 5 ]; then
should be:
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
Changes made:
Quoting variables is considered good practice.
ls is not a valid comparison operator, use le.
Separate single-bracket conditional expressions with &&.
Also you need a shebang in the first line of your script: #!/usr/bin/env bash
if [ $number -ge 2 && $number -ls 5 ]; then
should be
if [[ $number -ge 2 && $number -le 5 ]]; then
see help [[ for details
Try bellow code
echo "Enter number"
read input
if [[ $input ]] && [ $input -eq $input 2>/dev/null ]
then
if ((input >= 1 && input <= 4)); then
echo "Access Granted..."
break
else
echo "Wrong code"
fi
else
echo "$input is not an integer or not defined"
fi
2 changes needed.
Suggested by Sergio.
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
There is no need of break. only meaningful in a for, while, or until loop
while :; do
read option
if [[ $option -ge 1 && $option -lt 4 ]]; then
echo "correct"
c
break
else
echo "Incorrect option selected,choose an option between [1-4]"
fi
done

Compare Numbers not working properly (Bash Script in Hacker Rank)

According to the problem stated in the below link:
https://www.hackerrank.com/contests/bash-and-linux-shell-practice/challenges/bash-tutorials---comparing-numbers/problem
My code is working fine in Mac OSX terminal, but while submitting the same code in Hackerrank one of the test case is failing. I am not sure why this is happening. Would really appreciate any answers.
read X
read Y
if [[ $X > $Y ]]
then
echo "X is greater than Y"
elif [[ $X < $Y ]]
then
echo "X is less than Y"
else
echo "X is equal to Y"
fi
HackerRank Custom Test Case:
Compilation Successful
Input (stdin)
-100
100
Your Output
X is greater than Y
I'm not sure why you're getting that result; I get "X is less than Y" in actual bash. However, your script is actually wrong in a different way: in [[ ]], < and > do alphabetic comparison rather than numeric comparison. To understand the difference, consider that [[ 5 < 1000 ]] will come out as false, because "5" comes after "1" in character sorting order. To do numeric comparison, use -lt and -gt instead.
You can use the Bash double-parenthesis context ((...)) vs test context [[ ... ]] to get more typical arithmetic comparisons:
x=-5
y=5
if ((x>y)); then
echo "X is greater than Y"
elif ((x<y)); then
echo "X is less than Y"
else
echo "X is equal to Y"
fi
Or use an integer comparison inside [[ ... ]] test:
if [[ "$x" -gt "$y" ]]; then
echo "X is greater than Y"
elif [[ "$x" -lt "$y" ]]; then
echo "X is less than Y"
else
echo "X is equal to Y"
fi
Inside [[ ... ]] the <,> or == tests string comparisons.
Both of these methods only work with integers; to use floats, you need to use awk, bc or other float interpreter. Be sure to use double quotes "$x" in the [[ test ]] and the quotes and sigil are not required for (( ))
With user input, be sure to test that $x and $y are actual
numbers. Good tests here...

Bash script ignores the negative prefix on negative numbers

a=4;
b=7;
c=5;
x =[ a-b ]
if (x -gt c) then {
echo "x is greater"
} else {
echo " something"
}
I want to compare x and c ignoring the negative prefix of c.
I'm assuming you meant "negative prefix of x". There are a ton of errors in your code, are you sure you're writing in bash?
#!/bin/bash
typeset a=4 b=7 c=5
x=$(( a - b ))
x=${x//-/}
if [[ x -gt c ]]; then
echo "x is greater"
else
echo " something"
fi

Resources