Martin
Martin

Reputation: 1197

How does bash built-in test handle variable without quotes?

I am aware then in case of bash test one needs to use quotes around variable:

$ var=; [ "$var" = 1 ] || echo 'variable var not set'
variable var not set
$ var=; [ $var = 1 ] || echo 'variable var not set'
bash: [: =: unary operator expected
variable var not set
$ 

However, why do I receive this "unary operator expected" error if I do not use quotes around variable? In other words, what does $var mean to test if it has no quotes?

Upvotes: 0

Views: 302

Answers (1)

clt60
clt60

Reputation: 63952

Having a script.sh

var=
[ $var = 1 ] || echo 'variable var not set'

run it with bash -x - and get

+ var=
+ '[' = 1 ']'           #<--------- see this
script.sh: line 3: [: =: unary operator expected
+ echo 'variable var not set'
variable var not set

because the $var is empty (not set) into the test comes an empty string, what is lead to syntax error.

if do you use the [[ - bash extension like

var=
[[ $var = 1 ]] || echo 'variable var not set'

and again bash -x

+ var=
+ [[ '' = 1 ]]
+ echo 'variable var not set'
variable var not set

using [[ instead of [ gives you a bit more flexibility, but comers with a price. It is not portable, isn't defined in POSIX and so on...

Anyway, it IS A GOOD PRACTICE quote every variable. For example, if the variable will hold a filename with a space like: file name.txt - on the expansion without quotes you will get two words what is usually leads to error.

If you want know a bit deeper how bash works, when bash start evaluating your script doing the following:

  1. parsing and lexical analysis
  2. expansion
    1. brace expansion
    2. tidle expansion
    3. variable expansion
    4. artithmetic and other substitutions
    5. command substitution
    6. word splitting
    7. filename generation (globbing)
  3. removing quotes

as you can see, the last one is removing quotes.

You need to understand too, when bash evaluating at the final stage everywhere you have $variable is got replaced (expanded) with the variable content. Therefore, when the variable is empty got replaced with the empty string and the expression

$var=
[ $var = 1 ]

is evaluated exactly as

[ = 1]

what is (of course) error.

Upvotes: 2

Related Questions