User Tools

Site Tools


2018numeric_cmp

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
2018numeric_cmp [2018/09/07 11:06]
david
2018numeric_cmp [2018/09/07 14:02] (current)
david [Incorrect Numeric Comparisons (lexicographic order)]
Line 1: Line 1:
-====== ​Confusing comparison ​operators in BASH ======+~~NOTOC~~ 
 +====== ​Comparison ​operators in BASH ====== 
 + 
 +The multiple constructs that are available in BASH can lead to confusion.  
 + 
 +===== Brackets ===== 
 +  * Single brackets <​nowiki>​[ ]</​nowiki>​ are generally OK, but might allow some syntax to be interpreted as commands (thus causing errors) 
 +  * Double brackets <​nowiki>​[[ ]]</​nowiki>​ have less parsing, so are generally safer to use. 
 + 
 +===== Correct Numeric Comparisons ===== 
 +You must use the flag operators, or the symbolic operators inside double parentheses,​ to correctly compare values numerically. 
 +For example, say ''​a=2''​ and ''​b=10'':​  
 +  * <​nowiki>​[ 2 -lt 10 ]</​nowiki>​ is TRUE 
 +  * <​nowiki>​[[ 2 -lt 10 ]]</​nowiki>​ is TRUE 
 +  * <​nowiki>​[[ 2 -ge 10 ]]</​nowiki>​ is FALSE 
 +  * <​nowiki>​(( 2 < 10 ))</​nowiki>​ is TRUE 
 + 
 +===== Incorrect Numeric Comparisons (lexicographic order) ===== 
 +What results in an alphanumeric comparison (which has unexpected behavior), or a syntax error (which you may overlook) is the following:​ 
 +  * <​nowiki>​[[ 2 < 10 ]]</​nowiki>,​ alphanumerically FALSE 
 +  * <​nowiki>​[ 2 < 10 ]</​nowiki>,​ error; also FALSE. 
 + 
 +===== Importance of Testing ===== 
 + 
 +Whenever I have a question about a confusing syntax issue, I write a short test script to flesh out all the possibilities. To distinguish between the correct, incorrect, and error-producing constructs, I wrote a script that produces this table:
  
 ^ Syntax ^ Output ^  Error  ^ ^ Syntax ^ Output ^  Error  ^
Line 24: Line 48:
 | ''<​nowiki>​(( 10 -lt 2 ))</​nowiki>''​ | FALSE | ''<​nowiki>​((:​ 10 -lt 2 : syntax error (error token is "2 "​)</​nowiki>''​ | | ''<​nowiki>​(( 10 -lt 2 ))</​nowiki>''​ | FALSE | ''<​nowiki>​((:​ 10 -lt 2 : syntax error (error token is "2 "​)</​nowiki>''​ |
  
 +This script is:
 +
 +<code bash>
 +#​!/​usr/​bin/​env bash
 +# numeric_comparisons.bash - 
 +# Distinguish valid numeric versus ​
 +# lexicographic comparison constructs.
 +###
 +
 +a=2
 +b=10
 +echo "​Numeric comparisons:​ $a less than $b should be TRUE"
 +echo "​------------------------------------"​
 +echo -ne "[ $a < $b ]\t"
 +[ $a < $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ ! $a -lt $b ]\t"
 +[ ! $a -lt $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ $a \< $b ]\t"
 +[ $a \< $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[[ $a < $b ]]\t"
 +[[ $a < $b ]]  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[[ $a -lt $b ]]\t"
 +[[ $a -lt $b ]]  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ $a -lt $b ]\t"
 +[ $a -lt $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ \"​$a\"​ -lt \"​$b\"​ ]\t"
 +[ "​$a"​ -lt "​$b"​ ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "test $a -lt $b\t"
 +test $a -lt $b  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "(( $a < $b ))\t"
 +(( $a < $b ))  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "(( $a -lt $b ))\t"
 +(( $a -lt $b ))  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +# Reverse the values of a and b. 
 +# This should reverse the outcomes
 +# of the above commands.
 +a=10
 +b=2
 +echo "​Numeric comparisons:​ $a less than $b should be FALSE"
 +echo "​------------------------------------"​
 +echo -ne "[ $a < $b ]\t"
 +[ $a < $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ $a \< $b ]\t"
 +[ $a \< $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[[ $a < $b ]]\t"
 +[[ $a < $b ]]  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[[ $a -lt $b ]]\t"
 +[[ $a -lt $b ]]  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "[ $a -lt $b ]\t"
 +[ $a -lt $b ] && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "test $a -lt $b\t"
 +test $a -lt $b  && echo "​TRUE"​ || echo "​FALSE"​
 +
 +echo -ne "(( $a < $b ))\t"
 +(( $a < $b ))  && echo "​TRUE"​ || echo "​FALSE"​
  
 +echo -ne "(( $a -lt $b ))\t"
 +(( $a -lt $b ))  && echo "​TRUE"​ || echo "​FALSE"​
 +</​code>​
2018numeric_cmp.1536339991.txt.gz · Last modified: 2018/09/07 11:06 by david