read n
if ! ((n % 4)); then
echo "$n divisible by 4."
fi
The (( )) operator evaluates expressions as C arithmetic, and has a boolean return.
Hence, (( 0 )) is false, and (( 1 )) is true. [1]
The $(( )) operator also expands C arithmetic expressions, but instead of returning true/false, it returns the value instead. Because of this you can test the output if $(( )) in this fashion: [2]
[[ $(( n % 4 )) == 0 ]]
But this is tantamount to: if (function() == false). Thus the simpler and more idiomatic test is:
! (( n % 4 ))
[1]: Modern bash handles numbers up to your machine's intmax_t size.
[2]: Note that you can drop $ inside of (( )), because it dereferences variables within.
Single brackets ([..]) don't work for some tests. Try with double brackets ([[...]]) and enclose the mod in ((..)) to evaluate the % operator properly:
If you want something a bit more portable - for example, something that works in sh as well as in bash - use
if [ $(echo "$1 % 4" | bc) -eq 0 ]; then
...
An example
#!/bin/bash
#@file: trymod4.bash
if [ $(echo "$1 % 4" | bc) -eq 0 ]; then
echo "$1 is evenly divisible by 4"
else
echo "$1 is NOT evenly divisible by 4"
fi
$ chmod +x trymod4.bash
$ ./trymod4.bash 224
224 is evenly divisible by 4
$ ./trymod4.bash 223
223 is NOT evenly divisible by 4
I put this in, because you used the single [ ... ] conditional, which I usually associate with sh-compatible programs.
Check that this works in sh.
#!/bin/sh
#@file: trymod4.sh
if [ $(echo "$1 % 4" | bc) -eq 0 ]; then
echo "$1 is evenly divisible by 4"
else
echo "$1 is NOT evenly divisible by 4"
fi
$ chmod +x trymod4.sh
$ ./trymod4.sh 144
144 is evenly divisible by 4
$ ./trymod4.sh 19
19 is NOT evenly divisible by 4
All right, it works with sh.
Note the "theoretical" (but not always implemented as such) differences between [ ... ] and [[ ... ]] from this site (archived).