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
Last revision Both sides next revision
syntax:ccmd:conditional_expression [2012/11/02 13:02]
techlivezheng [Portability considerations]
syntax:ccmd:conditional_expression [2017/02/06 23:55]
fgrose [Description] Added note on quoted <PATTERN> forcing literal matching
Line 11: Line 11:
 The testing features basically are the same (see the lists for [[commands:​classictest | classic test command]]), with some additions and extensions. The testing features basically are the same (see the lists for [[commands:​classictest | classic test command]]), with some additions and extensions.
  
-^Operator^Description^ +^ Operator ​                                                           ^ Description ​                                                                                                                                                         
-|''​**(** <​EXPRESSION>​ **)**''​|Used to group expressions,​ to influence precedence of operators| +| ''​**(** <​EXPRESSION>​ **)**'' ​                                       | Used to group expressions,​ to influence precedence of operators ​                                                                                                     
-|''<​EXPRESSION1>​ **&&​** <​EXPRESSION2>''​|''​TRUE''​ if ''<​EXPRESSION1>''​ **and** ''<​EXPRESSION2>''​ are ''​TRUE''​ (do **not** use ''​-a''​!)| +| ''<​EXPRESSION1>​ **&&​** <​EXPRESSION2>'' ​                             | ''​TRUE''​ if ''<​EXPRESSION1>''​**and**''<​EXPRESSION2>''​ are ''​TRUE''​ (do **not** use ''​-a''​!) ​                                                                         
-|''<​EXPRESSION1>​ **||** <​EXPRESSION2>''​|''​TRUE''​ if ''<​EXPRESSION1>''​ **or** ''<​EXPRESSION2>''​ is ''​TRUE''​ (do **not** use ''​-o''​!)| +| ''<​EXPRESSION1>​ **||** <​EXPRESSION2>'' ​                             | ''​TRUE''​ if ''<​EXPRESSION1>''​**or**''<​EXPRESSION2>''​ is ''​TRUE''​ (do **not** use ''​-o''​!) ​                                                                           
-|''<​STRING>​ **==** <​PATTERN>''​|''<​STRING>''​ is checked against the pattern ''<​PATTERN>''​ - ''​TRUE''​ on a match| +| ''<​STRING>​ **==** <​PATTERN>'' ​                                      ​| ''<​STRING>''​ is checked against the pattern ''<​PATTERN>''​ - ''​TRUE''​ on a match \\ But see the note on quoting the pattern below¹. ​                                                                                  
-|''<​STRING>​ **=** <​PATTERN>''​|equivalent to the ''​==''​ operator| +| ''<​STRING>​ **=** <​PATTERN>'' ​                                       | equivalent to the ''​==''​ operator ​                                                                                                                                   
-|''<​STRING>​ **!=** <​PATTERN>''​|''<​STRING>''​ is checked against the pattern ''<​PATTERN>''​ - ''​TRUE''​ on **no match**| +| ''<​STRING>​ **!=** <​PATTERN>'' ​                                      ​| ''<​STRING>''​ is checked against the pattern ''<​PATTERN>''​ - ''​TRUE''​ on **no match** ​                                                                                ​
-|''<​STRING>​ **=~** <​ERE>''​|''<​STRING>''​ is checked against the **extended regular expression** ''<​ERE>''​ - ''​TRUE''​ on a match| +| ''<​STRING>​ **=~** <​ERE>'' ​                                          ​| ''<​STRING>''​ is checked against the [[https://​en.wikipedia.org/​wiki/​Regular_expression#​POSIX_extended|extended regular expression]] ''<​ERE>''​ - ''​TRUE''​ on a match  
-|See the [[commands:​classictest#​file_tests|classic test operators]]|Do **not** use the ''​test''​-typical operators ''​-a''​ and ''​-o''​ for AND and OR.|+| See the [[commands:​classictest#​file_tests|classic test operators]] ​ | Do **not** use the ''​test''​-typical operators ''​-a''​ and ''​-o''​ for AND and OR.                                                                                      | 
 +| See also [[syntax:​arith_expr#​comparisons|arithmetic comparisons]] ​  | Using ''​%%(( <​EXPRESSION>​ ))%%'',​ the [[syntax:​ccmd:​arithmetic_eval|arithmetic expression compound command]] ​                                                        |
  
-When the ''​==''​ and ''​!=''​ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules of [[syntax:​pattern | Pattern Matching]]. If the shell option ''​nocasematch''​ is enabled, the match is performed without regard to the case of alphabetic characters. Any part of the pattern may be quoted to force it to be  
-matched as a literal string. 
  
-:V4: When the operators ''<''​ and ''>''​ are used (string collation order), the test happens using the current locale when the ''​compat''​ level is greater than "​40"​.+When the ''​==''​ and ''​!=''​ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules of [[syntax:pattern | Pattern Matching]]. If the shell option ''​nocasematch''​ is enabled, the match is performed without regard to the case of alphabetic characters. 
 + 
 +¹Any part of the pattern may be quoted to force it to be matched as a literal string. 
 + 
 +When the operators ''<''​ and ''>''​ are used (string collation order), the test happens using the current locale when the ''​compat''​ level is greater than "​40"​.
  
 Operator precedence (highest => lowest): Operator precedence (highest => lowest):
Line 89: Line 92:
 </​code>​ </​code>​
  
-The interpretion ​of quoted regular expression special characters can be influenced by setting the ''​compat31''​ and ''​compat32'' ​(:​V4:​) ​shell options (''​compat*''​ in general). See [[internals:​shell_options]].+The interpretation ​of quoted regular expression special characters can be influenced by setting the ''​compat31''​ and ''​compat32''​ shell options (''​compat*''​ in general). See [[internals:​shell_options]].
  
 ==== Behaviour differences compared to the builtin test command ==== ==== Behaviour differences compared to the builtin test command ====
  
-:V4: As of Bash 4.1 alpha, the test primaries '<'​ and '>'​ (compare strings lexicographically) use the current locale settings, while the same primitives for the builtin test command don't. This leads to the following situation where both behave differently:​+As of Bash 4.1 alpha, the test primaries '<'​ and '>'​ (compare strings lexicographically) use the current locale settings, while the same primitives for the builtin test command don't. This leads to the following situation where they behave differently:​
 <​code>​ <​code>​
 $ ./cond.sh $ ./cond.sh
Line 117: Line 120:
   * Amongst the major "​POSIX-shell superset languages"​ (for lack of a better term) which do have ''<​nowiki>​[[</​nowiki>'',​ the test expression compound command is one of the very most portable non-POSIX features. Aside from the ''​=~''​ operator, almost every major feature is consistent between Ksh88, Ksh93, mksh, Zsh, and Bash. Ksh93 also adds a large number of unique pattern matching features not supported by other shells including support for several different regex dialects, which are invoked using a different syntax from Bash's ''​=~'',​ though ''​=~''​ is still supported by ksh and defaults to ERE.   * Amongst the major "​POSIX-shell superset languages"​ (for lack of a better term) which do have ''<​nowiki>​[[</​nowiki>'',​ the test expression compound command is one of the very most portable non-POSIX features. Aside from the ''​=~''​ operator, almost every major feature is consistent between Ksh88, Ksh93, mksh, Zsh, and Bash. Ksh93 also adds a large number of unique pattern matching features not supported by other shells including support for several different regex dialects, which are invoked using a different syntax from Bash's ''​=~'',​ though ''​=~''​ is still supported by ksh and defaults to ERE.
   * As an extension to POSIX ERE, most GNU software supports backreferences in ERE, including Bash. According to POSIX, only BRE is supposed to support them. This requires Bash to be linked against glibc, so it won't necessarily work on all platforms. For example, <​code>​$(m='​(abc(def))(\1)(\2)';​ [[ abcdefabcdefdef =~ $m ]]; printf '<​%s>​ ' $? "​${BASH_REMATCH[@]}"​ )</​code>​ will give ''<​0>​ <​abcdefabcdefdef>​ <​abcdef>​ <def> <​abcdef>​ <​def>''​.   * As an extension to POSIX ERE, most GNU software supports backreferences in ERE, including Bash. According to POSIX, only BRE is supposed to support them. This requires Bash to be linked against glibc, so it won't necessarily work on all platforms. For example, <​code>​$(m='​(abc(def))(\1)(\2)';​ [[ abcdefabcdefdef =~ $m ]]; printf '<​%s>​ ' $? "​${BASH_REMATCH[@]}"​ )</​code>​ will give ''<​0>​ <​abcdefabcdefdef>​ <​abcdef>​ <def> <​abcdef>​ <​def>''​.
-  * the behaviour of the ''​=~''​ (regex) operator ​has changed between ​Bash 3.0 and Bash 3.2+  * the ''​=~''​ (regex) operator ​was introduced in Bash 3.0and its behaviour changed in Bash 3.2: since 3.2, quoted strings and substrings are matched as literals by default.
   * the behaviour of the ''<''​ and ''>''​ operators (string collation order) has changed since Bash 4.0   * the behaviour of the ''<''​ and ''>''​ operators (string collation order) has changed since Bash 4.0
 ===== See also ===== ===== See also =====
  • syntax/ccmd/conditional_expression.txt
  • Last modified: 2017/02/08 22:30
  • by fgrose