2

The Bash reference section on conditional constructs says:

When the ‘==’ and ‘!=’ operators are used, the string to the right of the 
operator is considered a pattern and matched according to the rules described 
below in Pattern Matching, as if the extglob shell option were enabled. ...
An additional binary operator, ‘=~’, is available, with the same precedence as 
‘==’ and ‘!=’. When it is used, the string to the right of the operator is 
considered an extended regular expression and matched accordingly (as in regex 
3)). 

But then I try this:

$ [[ -good == -* ]] ; echo $?
0
$ [[ -g == -* ]] ; echo $?
bash: syntax error in conditional expression
bash: syntax error near `-*'
$ [[ -g == -? ]] ; echo $?
bash: syntax error in conditional expression
bash: syntax error near `-?'

Then I try the regex matching operator =~:

$ [[ -good =~ -.* ]] ; echo $?
0
$ [[ -g =~ -.* ]] ; echo $?
bash: syntax error in conditional expression
bash: syntax error near `-.*'
$ [[ -g =~ -.? ]] ; echo $?
bash: syntax error in conditional expression
bash: syntax error near `-.?'

Why the syntax errors?

2 Answers 2

4

Well you have to be careful that the text to the left of ==, =~ or != is not one of the operators recognized in Bash conditional expressions.

In your case, -g tests for a setgid bit set. If you had provided something that is not recognized as an operator in this context, then it would work:

$ [[ -i == -* ]] ; echo $?
0
$ [[ -i == -? ]] ; echo $?
0
$ [[ -i =~ -.* ]] ; echo $?
0
$ [[ -i =~ -.? ]] ; echo $?
0

One way to reliably provide any string would be to quote it, so it is recognized not as an operator but as just a string:

$ [[ "-good" == -* ]] ; echo $?
0
$ [[ "-g" == -* ]] ; echo $?
0
$ [[ "-g" == -? ]] ; echo $?
0
$ [[ "-good" =~ -.* ]] ; echo $?
0
$ [[ "-g" =~ -.* ]] ; echo $?
0
$ [[ "-g" =~ -.? ]] ; echo $?
0

However take care not to quote the right hand side of the operator since it will prevent that from being recognized as a pattern:

$ [[ "-good" == "-*" ]] ; echo $?
1
$ [[ "-g" == "-*" ]] ; echo $?
1
$ [[ "-g" == "-?" ]] ; echo $?
1
$ [[ "-good" =~ "-.*" ]] ; echo $?
1
$ [[ "-g" =~ "-.*" ]] ; echo $?
1
$ [[ "-g" =~ "-.?" ]] ; echo $?
1
0

We should put the string inside quotes to evaluate them as strings. If we try to evaluate a string having embedded hyphen(-) then shell will consider it as an option to test but not as string. For more information on the operators you can check this here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .