Difference between revisions of "What does "unary operator expected" mean"

From Linuxintro
imported>ThorstenStaerk
 
(11 intermediate revisions by one other user not shown)
Line 1: Line 1:
When you work with Linux scripts on the command line, you will sometimes get an error message saying
+
The bash message
 
  unary operator expected
 
  unary operator expected
And you may wonder what this means. To give you an example, let's write a short bash script.
+
means that you do a comparison where one site is empty for example
 +
if [ $name = "foo" ]
 +
and $name is empty. Then the bash shell internally replaces $name by an empty string and it will be interpreted as
 +
if [ = "foo" ]
 +
and this is not a valid expression.
  
= The script =
+
The solution is to quote variable names like this:
Just copy and paste the lines below into a Linux Shell:
+
  if [ "$name" = "foo" ]
  [[cat]] >test.sh<<EOF
+
Then it will work.
[[echo]] "how is your name? "
 
read name
 
if [ $name = "Thorsten" ]; then echo "I know you"; fi
 
EOF
 
chmod 777 test.sh
 
After you did this, you have a script test.sh that will ask you for your name and say "I know you" if your name is Thorsten. You can call the script using the [[command]]
 
./test
 
Now if you don't enter a name and just press enter you will get this:
 
# ./test.sh
 
how is your name?
 
 
./test.sh: line 3: [: =: unary operator expected
 
This is clearly a problem in line 3. $name is replaced by ''nothing'' when the shell executes the line. So the remainder of the line reads
 
if [ = "Thorsten" ]; then echo "I know you"; fi
 
Which does not work because you cannot compare ''nothing'' with "Thorsten".
 
  
= The solution =
+
= Shell scripting tutorial =
There is a simple trick to avoid this kind of error messages already when programming. For example if you add an "x" left and right next to the equal sign in line 3:
+
Try the tutorial [[BaBE - Bash By Examples]] to avoid this and similar mistakes in the future.
if [ x$name = "xThorsten" ]; then echo "I know you"; fi
 
The shell may still replace $name by ''nothing'', but then the x will stay and the command will be after evaluation:
 
  if [ x = "xThorsten" ]; then echo "I know you"; fi
 
And there will not be an error message any longer.
 
  
= Outlook =
+
= Debugging bash scripts =
You can also debug the script line-by-line using bashdb. Bashdb shows all commands that are being executed, just like [[gdb]] or [[strace]], but for bash scripts:
+
You can also debug the script line-by-line using bash -x. bash -x shows all commands that are being executed, just like [[gdb]] or [[strace]], but for bash scripts:
 
<pre>
 
<pre>
tstaerk@ubuntu:~$ bashdb test.sh  
+
tweedleburg:~ # bash -x test.sh  
bashdb debugger, release 4.2-0.6
+
+ echo 'how is your name? '
 +
how is your name?
 +
+ read name
  
Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Rocky Bernstein
+
+ '[' = foo ']'
This is free software, covered by the GNU General Public License, and you are
 
welcome to change it and/or distribute copies of it under certain conditions.
 
 
 
(/home/tstaerk/test.sh:1):
 
1:      echo "how is your name? "
 
bashdb<0> step
 
how is your name?
 
(/home/tstaerk/test.sh:2):
 
2:      read name
 
bashdb<1> step
 
Thorsten
 
(/home/tstaerk/test.sh:3):
 
3:      if [ = "Thorsten" ]; then echo "I know you"; fi
 
bashdb<2> step
 
 
test.sh: line 3: [: =: unary operator expected
 
test.sh: line 3: [: =: unary operator expected
(/usr/bin/bashdb:1):
 
1:      #!/bin/bash
 
bashdb<3> step
 
Debugged program terminated normally. Use q to quit or R to restart.
 
bashdb<4>
 
 
</pre>
 
</pre>
  
Line 61: Line 29:
 
* [[troubleshooting]]
 
* [[troubleshooting]]
 
* [[error messages]]
 
* [[error messages]]
 +
* [[shell scripting tutorial]]

Latest revision as of 19:15, 24 December 2014

The bash message

unary operator expected

means that you do a comparison where one site is empty for example

if [ $name = "foo" ]

and $name is empty. Then the bash shell internally replaces $name by an empty string and it will be interpreted as

if [ = "foo" ]

and this is not a valid expression.

The solution is to quote variable names like this:

if [ "$name" = "foo" ]

Then it will work.

Shell scripting tutorial

Try the tutorial BaBE - Bash By Examples to avoid this and similar mistakes in the future.

Debugging bash scripts

You can also debug the script line-by-line using bash -x. bash -x shows all commands that are being executed, just like gdb or strace, but for bash scripts:

tweedleburg:~ # bash -x test.sh 
+ echo 'how is your name? '
how is your name? 
+ read name

+ '[' = foo ']'
test.sh: line 3: [: =: unary operator expected

See also