How do I do if statement arithmetic in bash?

BashScripting

Bash Problem Overview


I want to do something like this:

if [ $1 % 4 == 0 ]; then
...

But this does not work.

What do I need to do instead?

Bash Solutions


Solution 1 - Bash

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.

Solution 2 - Bash

a=4
if [ $(( $a % 4 )) -eq 0 ]; then                                
     echo "I'm here"
fi

Solution 3 - Bash

Single brackets ([..]) don't work for some tests. Try with double brackets ([[...]]) and enclose the mod in ((..)) to evaluate the % operator properly:

if [[ $(( $1 % 4 )) == 0 ]]; then

More details are in 7.2. More advanced if usage.

Solution 4 - Bash

This might work for you:

((a%4==0)) && echo "$a is divisible by 4" || echo "$a is not divisible by 4"

or more succinctly:

((a%4)) && echo "$a is not divisible by 4" || echo "$a is divisible by 4"

Solution 5 - Bash

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).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjmasterxView Question on Stackoverflow
Solution 1 - BashgunsView Answer on Stackoverflow
Solution 2 - BashJan VorcakView Answer on Stackoverflow
Solution 3 - BashchownView Answer on Stackoverflow
Solution 4 - BashpotongView Answer on Stackoverflow
Solution 5 - Bashbballdave025View Answer on Stackoverflow