Check if a number is even in shell - bash

I need to check if a number is even.
Here's what I've tried.
newY="281"
eCheck=$(( $newY % 2 ))
echo $newY
echo $eCheck
while [ $eCheck -eq 0 ]; do
newY=$((newY-1))
eCheck=$(( $newY % 2 ))
echo $newY
done
...
returns eCheck = 1
how can it be? 281/2 = 140.5
i've also tried using bc, but it went into an infinite loop eCheck=$(echo "scale=1;$newY%2" | bc)

Nici is right, "%" is the modulo, and gives you the remainder of the division.
Your script can be simplified as follows :
if [[ $((var % 2)) -eq 0 ]];
then echo "$var is even";
else echo "$var is odd";
fi

You can do a simple :
eCheck=$(( $newY & 1 ))
to utilize the bitwise operators in bash.

The % operator computes the remainder. So 281 % 2 is 1, because 281 divided by 2 is 140 with a remainder of 1.

#!/usr/bin/env bash
[[ $( expr $1 % 2 ) -eq 0 ]] && echo "Even Number" || echo "Odd Number"

You are so close! Think of it like this. There are only two possible answers for Y in the expression
Y = X % 2
for ALL values of X. What are they? Play with a few values of X to see if you can come up with the values for Y.
Next, is there anything you can determine about what the value of Y says about the value of X? That is, can you use the value of Y to answer the problem you are trying to solve?

This can be done using expr
evenCheck=$(expr $newY % 2)
if [ $evenCheck = 0 ] ;
then echo "number is even";
else echo "number is odd";
fi
done

As you mention you are checking even for single no, So there is no need to use a loop. Here is my bit of code.
read -p "Enter a number: " num
if [ $((num%2)) -eq 0 ]
then
echo "Entered Number is even:"
else
echo "Entered Number is odd:"
fi

Since this question is tagged as Bash, the right way to check if a number is even in Bash is:
if ((num%2 == 0)); then
echo "The number is even"
fi
or, more even shorter:
if ((num % 2)); then
echo "The number is even"
fi
We don't need to use [[ ... ]] in this case.
See also:
Difference between Bash operators double vs single brackets and (( (on Unix & Linux Stack Exchange)
How do I check whether a variable has an even numeric value?

#!bin/bash
echo "Type the input integer, followed by [Enter]:"
read x
if [ $((x%2)) -eq 0 ]; then
echo "$x is even"
else
echo "$x is odd"
fi
Yes "%" is modulo, it gives you the remainder like others have mentioned

Related

ge vs double equal in bash

I am trying to solve a hackerrank exercise.
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird
My code is as follows:
read n
if [ $n%2==0 ]; then
if [ $n -ge 6 ] && [ $n -le 20 ]; then
echo "Weird"
else
echo "Not Weird"
fi
else
echo "Weird"
fi
When I give the input as 3, the result I get is Not Weird which is not correct same for 1 I get Not Weird. However, when I try this:
read n
if [ $(($n%2)) -eq 0 ]; then
if [ $n -ge 6 ] && [ $n -le 20 ]; then
echo "Weird"
else
echo "Not Weird"
fi
else
echo "Weird"
fi
I get the right result. What is the difference?
[ ] (or test) builtin:
==, or to be POSIX compliant =, does a string comparison
-eq does a numeric comparison
Note: == and -eq (and other comparisons) are parameters to the [ command, so they must be separated by whitespace, so $n%2==0 is invalid.
[[ ]] keyword:
is as [ except that it does pattern matching. Being a keyword rather than a builtin, expansion with [[ is done earlier in the scan.
(( )) syntax
Carries out arithmetic evaluation as with the let builtin. Whitespace separators are not mandatory. Using a leading $ to expand a variable is not necessary and is not recommended since it changes the expansion order.
For truth evaluation inside if-else, bash provides ((..)) operators with no need of a $ on the front.
n=5
if (( (n % 2) == 0 )); then
echo "Something"
if (( n >= 6 )) && (( n <= 20 )); then
echo "Some other thing"
else
echo "Other else thing"
fi
else
echo "Something else"
fi
Read here for more information.

Multiple conditions with arithmetic, comparison and regular operators in if statement

I am trying to write a script that reads three integers, then checks if the sum of any two of those numbers is greater than the third one. If that is true, then it checks if those numbers are equal, and prints a message. If not, it checks whether any two of the numbers are equal and prints another message. If all of the above are false, it prints a message saying that all numbers are different.
I have tried to put that in the following nested conditional:
read X
read Y
read Z
if [ $X + $Y > $Z ] && [ $X + $Z > $Y ] && [ $Y + $Z > $X ]
then
if [ $X = $Y = $Z ]
then
echo "All numbers are equal."
elif [ [ $X = $Y ] && [ $X != $Z ] ] || [ [ $X = $Z ] && [ $X != $Y ] ] || [ [ $Z = $Y ] && [ $X != $Y ] ]
then
echo "Two of the numbers are equal."
else
echo "None of the numbers is equal to another."
fi
fi
I have tried all types of combinations with brackets and parentheses (the above is just one of them), but none of them has worked so far.
I have already taken a look at related posts:
Bash if statement with multiple conditions throws an error
Bash: Two conditions in if
How to represent multiple conditions in a shell if statement?
but I haven't found any that are covering conditions with arithmetic operators in them.
Can anyone please tell me what is the right way?
(Edit: I forgot to mention in the original post that I am new to bash, so please excuse me for any profound mistakes I might have made. I am still trying to figure out how things are working.)
Here is a variation on Inian's answer taking advantage of arithmetic operations not requiring $ to expand variables, them accepting logical operators, and the fact that the first test for equality of all numbers allows the following test to be simplified.
Please note that checking if the values read actually are integer would be a good idea to avoid unexpected behavior.
#!/bin/bash
read X
read Y
read Z
if
(( X+Y>Z || X+Z>Y || Y+Z>X ))
then
if
(( X==Y && Y==Z ))
then
echo "All numbers are equal"
elif
(( X==Y || X==Z || Z==Y ))
then
echo "Two of the numbers are equal"
else
echo "All three numbers are different"
fi
fi
The $(( )) for of arithmetic expression expands to the result of the evaluation of the expression found inside. The (( )) for acts as a command that returns 0 if the expression is a test that results in a "true" value OR if it evaluates to a non-zero number, and a non-zero value otherwise. This second form is very useful for tests.
As an aside, I like using the properties of (( )) to handle on/off options in scripts. For instance, ((state_variable)) will evaluate to "false" if the variable is null or 0, and "true" otherwise, which maps nicely to how such a variable is intuitively expected to behave.
You could also do it a different way by just incrementing for matches and using a case statement.
Should make it easier to scale with more variables as well.
#!/bin/bash
read X
read Y
read Z
((Matches+=(X==Y)))
((Matches+=(Y==Z)))
((Matches+=(X==Z)))
case "$Matches" in
0) echo "None of the numbers is equal to another.";;
1) echo "Two of the numbers are equal.";;
3) echo "All numbers are equal.";;
esac
A completely different approach to tackle the problem.
#!/bin/bash
declare -A a # declare associative array a
read x; a[$x]=$x
read x; a[$x]=$x
read x; a[$x]=$x
case ${#a[#]} in
1) echo "All numbers are equal." ;;
2) echo "Two of the numbers are equal." ;;
3) echo "None of the numbers is equal to another." ;;
esac
One-liner function, condensed from 123's answer:
n=(No Two "" All)
3a(){ echo "${n[$((($1==$2)+($1==$3)+($3==$2)))]} numbers are equal." ; }
Show all three cases:
3a 1 1 1 ; 3a 1 1 2 ; 3a 1 2 3
All numbers are equal.
Two numbers are equal.
No numbers are equal.

Shell Script command not found error

Below my script for up to n prime numbers. When I run it, it always shows an error that command not found in line 12 and 18 both. What am I doing wrong?
clear
echo"enter the number upto which you want prime numbers : "
read n
for((i=1;i<=n;i++))
do
flag=0
for((j=2;j<i;j++))
do
if [expr $i % $j-eq 0]
then
flag=1
fi
done
if [$flag-eq 0]
then
echo $i
fi
done
As pointed out in comments, you must use spaces around [ and ], as well as the comparison operators. Even more safe when using [ and ] is quoting your variables to avoid word splitting (not actually required in this specific case, though).
Additionally, you want to compare the output of expr to 0, so you have to use command substitution:
if [ $(expr "$i" % "$j") -eq 0 ]
and
if [ "$flag" -eq 0 ]
Since you're using Bash, you can use the (( )) compound command:
if (( i % j == 0 ))
and
if (( flag == 0 ))
No expr needed, no command substitution, no quoting required, no $ required, and the comparison operators have their "normal", expected meaning.
There are a number of syntax errors other than the brackets of if statement. Kindly go through the piece of code below. I have checked it running on my system.
#!/bin/sh
echo "enter the number upto which you want prime numbers : "
read n
for((i=1;i<=n;i++))
do
flag=0
for((j=2;j<i;j++))
do
if [ `expr $i % $j` -eq 0 ]
then flag=1
fi
done
if [ $flag -eq 0 ]
then echo $i
fi
done

Bash Comparing Whole number to Decimal Errors

I have a bash script in which I am attempting to compare a variable containing a whole number
VAR1=1
The real number to compare to, can be a decimal
VAR2=1.5
When I try:
if [[ $VAR1 -ge $VAR2]];
I am presented with a syntax error: invalid arithmetic operator
The problem is, when I try the >= string comparison, the result is always false irregardles of whether it logically is or not.
My question is, how can I fix this and do the arithmatic comparison?
Code Block
if [ $(bc -l <<<"$CPUUSAGE >= $MAXCPU") || $(bc -l <<<"$FREEMEM <= $MAXMEM") || $NUMHTTPD -ge $MAXHTTPD || $NUMMYSQL -ge $MAXMYSQL || $NUMPROCS -ge $MAXPROCESSES ]];
then
SendMessage;
sync ; echo 3 > /proc/sys/vm/drop_caches;
echo "Message Sent";
fi;
Bash doesn't support floating point numbers.
Try bc:
(( $(bc -l <<<"$v1 >= $v2") )) && echo "v1 is greater than or equal to v2"
I have used some bashisms here, notably the (( arithmetic context )) and <<< as an alternative to echoing the string to bc. The output of bc will be 1 or 0, depending on whether the statement is true or false. The message will only be echoed if the result is true.
The -l switch is shorthand for --mathlib, which as hek2mgl rightly asserts, is needed when working with floating point numbers.
If you want a fully-fledged if statement, you can do that as well:
if (( $(bc -l <<<"$v1 >= $v2") )); then
echo "v1 is greater than or equal to v2"
else
echo "v1 is less than v2"
fi
For the example in your question, you could use this:
if (( $(bc -l <<<"$CPUUSAGE >= $MAXCPU || $FREEMEM <= $MAXMEM") )) || [[ $NUMHTTPD -ge $MAXHTTPD || $NUMMYSQL -ge $MAXMYSQL || $NUMPROCS -ge $MAXPROCESSES ]]; then echo; fi
I've combined the two conditions in bc to save you calling the tool twice. I've also wrapped that part in an arithmetic context and used an extended test [[ for the rest.
bash does not support floating point operations. You could use bc for that:
if [ $(bc --mathlib <<< "$var1 >= $var2") = "1" ] ; then
echo "$var2 is greater than or equal to $var2"
fi
Note that unless you pass the --mathlib option, even bc would not support floating point operations.
AWK can do the trick too:
#!/bin/sh
VAR1=1
VAR2=1.5
if awk "BEGIN {exit $VAR1 >= $VAR2 ? 0 : 1}"
then
echo "$VAR1 is greater than or equal to $VAR2"
else
echo "$VAR2 is greater than or equal to $VAR1"
fi

How to write a condition in bash

check even number - OK
if [ $(( $n % 2 )) -eq 0 ]
then
echo "$n is even number"
fi
how to check odd number ?
if [ $(( $n % ????? )) -eq 0 ]
then
echo "$n is odd number"
fi
Thank
Use "not equal 0":
if [ $(( $n % 2)) -ne 0 ]
then
echo "$n is odd"
fi
See also: http://tldp.org/LDP/abs/html/comparison-ops.html
You can also use "n%2 equals 1" since the remainder of an odd number divided by two is one:
if [ $(( $1 % 2)) -eq 1 ]
then
echo "$1 is odd"
fi
But the former (not equal 0) is the more general case, so I would prefer it.
All the answers above use a single square bracket [ which is outdated in bash (we're talking about bash, right?). The best practice to achieve the determination of an odd or even number n is:
if (( n%2==0 )); then
printf "%d is even\n" $n
else
printf "%d is odd\n" $n
fi
or, as the OP wants it, i.e., check if n is odd:
if (( n%2 )); then
printf "%d is odd\n" $n
fi
echo -n "Enter numnber : "
read n
rem=$(( $n % 2 ))
if [ $rem -eq 0 ]then
echo "$n is even number"
else
echo "$n is odd number"
fi
I prefer the simplicity of:
x=8; ((x%2)) || echo even
x=7; ((x%2)) && echo odd

Resources