3

How can I test whether a number in a bash script is 0 (zero) or a positive whole number?

0

3 Answers 3

4

The common idiom for that is to check if the variable's value consists of nothing but numbers. With newer bash shells, you can use =~ and a regular expression:

zero_or_positive_integer(){
    for i in "$@"; do
        if [[ "$i" =~ ^[0-9]+$ ]]; then
            echo "YES $i is either 0 or a positive integer"
        else
            echo "NO $i is neither 0 nor a positive integer"
        fi
    done
}

Which results in:

$ zero_or_positive_integer foo -2 1.5 0 12
NO foo is neither 0 nor a positive integer
NO -2 is neither 0 nor a positive integer
NO 1.5 is neither 0 nor a positive integer
YES 0 is either 0 or a positive integer
YES 12 is either 0 or a positive integer
4

To do tests, you typically use the [ or [[ operator. [ is a synonym for the command test (not part of Bash specifically)

$ help [
[: [ arg... ]
    Evaluate conditional expression.
    
    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.
$ man test
[...]
       INTEGER1 -eq INTEGER2
              INTEGER1 is equal to INTEGER2
       INTEGER1 -ge INTEGER2
              INTEGER1 is greater than or equal to INTEGER2
[...]

So it looks like you can write (don't forget spaces -- [ is just a built-in program, so keep its arguments separate)

if [ "$var" -eq 0 ]; then
  echo "Zero"
elif [ "$var" -gt 0 ]; then
  echo "Positive"
fi

Note that if $var is not an integer, this will result in an error. We're assuming $var is some integer already.

If you're not sure that $var is an integer, I'm not aware of a great test, so here's some code using regular expressions:

if [[ "$var" =~ ^[1-9][0-9]+$ ]]; then
  echo "Positive"
elif [[ "$var" = 0 ]]; then
  echo "Zero"
else
  echo "Other"
fi
1
  • 7
    Actually, [ is part of the bash shell since bash provides it as a builtin. It's just that there is also another [, often found at /usr/bin/[ which is a standalone executable and mandated by POSIX. However, unless you call it explicitly by running /usr/bin/[, you will never see it since shell builtins take priority. You can confirm this by running type [ and type -a [. The help message you show (and all help messages since help is a bash thing) is about the builtin, very much a part of bash. Commented Sep 19, 2022 at 21:18
2

The printf Bash built-in will read a string and verify that it can be successfully converted as specified by the format string. You can check the status "${?}", use -v to put the value into a temporary variable, and discard the error message with 2>/dev/null.

$ a=-56
$ printf -v q '%d' "${a}"; echo $? "${q}"
0 -56
$ a=-56.3
$ printf -v q '%d' "${a}"; echo $? "${q}"
bash: printf: -56.3: invalid number
1 -56
$ a=315.8e4
$ printf -v q '%d' "${a}"; echo $? "${q}"
bash: printf: 315.8e4: invalid number
1 315
$ printf -v q '%f' "${a}"; echo $? "${q}"
0 3158000.000000
1
  • 3
    I think you misread the question: the OP wants the test to succeed only on 0 and positive integers but your (otherwise really neat!) approach also returns success for negative integers. Commented Sep 19, 2022 at 21:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.