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