Bash: Numeric comparison
From FVue
Contents
Problem
The following tests – using greater than (>) – do not work:
# Redirects to file `5'. Returns true unexpected. [ 3 > 5 ] && echo true # WRONG # Does string - not numeric - comparison. Returns true unexpected. [[ 5 > 34 ]] && echo true # WRONG
Solutions
Solution 1: Arithmetic command: ((..))
Do arithmetic evaluation, using the `((..))' syntax:
((3 > 5)) && echo true
Compared with the other solutions, this is executed fastest, see #Time comparison.
This command is available since bash-2.0-beta2.
Solution 2: Arithmetic binary operators: -eq, -ne, -lt, -le, -gt, -ge
Use the -eq, -ne, -lt, -le, -gt, or -ge arithmetic binary operators for numeric comparison. For example:
[ 3 -gt 5 ] && echo true [[ 5 -gt 34 ]] && echo true
Time comparison
When comparing execution speed of the different solutions, ((..)) is executed fastest, followed by [[..]] and finally [..]:
time
------------------------------------------------------------------------
real [%] real [s] user [s] sys [s]
---------------------------------------- -------- -------- -------
0 100
----------------------------------------
((..)) ############################ 2.001 1.960 0.044
[[..]] ############################### 2.149 2.092 0.056
[..] ######################################## 2.810 2.704 0.104
---------------------------------------- -------- -------- -------
Table 1: Time consumed doing 2,000 numeric comparisons. See #Appendix A: time_numeric.sh for the code used.
See also
- BashPitfalls - Greg's Wiki
- Comprehensive list of bash pitfalls, including this numeric comparison one.
Appendix A: time_numeric.sh
MAX=20000
echo bash-$BASH_VERSION
echo
echo '((..))'
f() {
local i
for (( i=MAX; i > 0; i-- )); do
((3 > 5))
done
}
time f
echo
echo '[[..]]'
f() {
local i
for (( i=MAX; i > 0; i-- )); do
[[ 3 -gt 5 ]]
done
}
time f
echo
echo '[..]'
f() {
local i
for (( i=MAX; i > 0; i-- )); do
[ 3 -gt 5 ]
done
}
time f
Example output:
$ . time_numeric.sh bash-3.2.39(1)-release ((..)) real 0m2.001s user 0m1.960s sys 0m0.044s [[..]] real 0m2.149s user 0m2.092s sys 0m0.056s [..] real 0m2.810s user 0m2.704s sys 0m0.104s
Advertisement