1

Please follow the following example (please notice that STRING is null)

Get Error

 [root@linux /tmp]# STRING=
 [root@linux /tmp]#  [ $STRING = dog ] && echo "yes its a dog"
 bash: [: =: unary operator expected

Syntax without Error

 [root@linux /tmp]# STRING=
 [root@linux /tmp]# [[ $STRING = dog ]] && echo "yes its a dog"
 [root@linux /tmp]# [[ $STRING != dog ]] && echo "yes its a dog"
 yes its a dog

Why when I am using Single Square brackets I get - unary operator expected ?

But in case of Double Square brackets the syntax give good results

maihabunash
  • 1,632
  • 9
  • 34
  • 60

3 Answers3

4

Unlike [[ ]], single square brackets are subject to word splitting like normal commands. Think of it similarly as passing arguments to test builtin. [[ ]] are special and variables within it are not split with IFS. This is why it's preferable to use [[ ]] since it's more efficient and safer.

This one is just one of the things you can't do with [. With [ you'd play around with { } and ( ) to make it work. Note that ( ) summons a subshell and { } would always need a semicolon in the end which is ugly. However you can do it safely with [[ ]]:

[[ a != b && c != d && ( something || something ) ]]

By the way to fix your problem you have to place the variable in double-quotes to prevent splitting:

[ "$STRING" = dog ]

With [[ it's not needed.

Sere Word Splitting: https://www.gnu.org/software/bash/manual/html_node/Word-Splitting.html

Add:

It seems like $STRING there was actually skipped as an argument for being empty instead of being split. Similarly the concept of it being interpreted as a normal command would apply and applying double quotes would fix it.

konsolebox
  • 72,135
  • 12
  • 99
  • 105
2

Because [[ is special. [ needs to retain Bourne shell compatibility, including its limitations. Since [[ is a construct introduced separately in bash, it can be fixed.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

It's tough to search on, but this is very frequently asked. Try googling for "bash square brackets" and you will see lots of discussions on this topic, mostly on SO:

https://www.google.com/search?q=bash+square+brackets

https://serverfault.com/questions/52034/what-is-the-difference-between-double-and-single-square-brackets-in-bash

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29

The short answer is to always use [[ unless you know otherwise...

Community
  • 1
  • 1
Ian McGowan
  • 3,461
  • 3
  • 18
  • 23