How can I test whether a number in a bash script is 0 (zero) or a positive whole number?
3 Answers
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
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
-
7Actually,
[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 runningtype [andtype -a [. Thehelpmessage you show (and allhelpmessages sincehelpis a bash thing) is about the builtin, very much a part of bash.2022-09-19 21:18:12 +00:00Commented Sep 19, 2022 at 21:18
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
-
3I 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.2022-09-19 21:46:57 +00:00Commented Sep 19, 2022 at 21:46