"unary operator expected" error in Bash if condition

BashShell

Bash Problem Overview


This script is getting an error:

elif [ $operation = "man" ]; then
    if [ $aug1 = "add" ]; then         # <- Line 75
	echo "Man Page for: add"
	echo ""
	echo "Syntax: add [number 1] [number 2]"
	echo ""
	echo "Description:"
	echo "Add two different numbers together."
	echo ""
	echo "Info:"
	echo "Added in v1.0"
	echo ""
elif [ -z $aug1 ]; then
	echo "Please specify a command to read the man page."
else
	echo "There is no manual page for that command."
fi

I get this error:

calc_1.2: line 75: [: =: unary operator expected

Bash Solutions


Solution 1 - Bash

If you know you're always going to use Bash, it's much easier to always use the double bracket conditional compound command [[ ... ]], instead of the POSIX-compatible single bracket version [ ... ]. Inside a [[ ... ]] compound, word-splitting and pathname expansion are not applied to words, so you can rely on

if [[ $aug1 == "and" ]];

to compare the value of $aug1 with the string and.

If you use [ ... ], you always need to remember to double quote variables like this:

if [ "$aug1" = "and" ];

If you don't quote the variable expansion and the variable is undefined or empty, it vanishes from the scene of the crime, leaving only

if [ = "and" ];

which is not a valid syntax. (It would also fail with a different error message if $aug1 included white space or shell metacharacters.)

The modern [[ operator has lots of other nice features, including regular expression matching.

Solution 2 - Bash

It took me a while to find this, but note that if you have a spacing error, you will also get the same error:

[: =: unary operator expected

Correct:

if [ "$APP_ENV" = "staging" ]

vs

if ["$APP_ENV" = "staging" ]

As always, setting -x debug variable helps to find these:

set -x

Solution 3 - Bash

Try assigning a value to $aug1 before use it in if[] statements; the error message will disappear afterwards.

Solution 4 - Bash

This error can also occur reading numerical input that could possibly be blank (to accept a default option).

The solution is to structure the if statement with multiple conditions & test for an empty variable first.

For example:

# sanitise input
var=$(echo $ans | tr -cd "[:digit:]")

if [ -z "$var" ] || [ "$var" -lt 1 ]; then
   do_something
fi

I had to solve this unary operator expected issue in remove_old_pkgs() of the helper script abk for Arch Sign Modules.

See also 6.4 Bash Conditional Expressions

Solution 5 - Bash

You can also set a default value for the variable, so you don't need to use two "[", which amounts to two processes ("[" is actually a program) instead of one.

It goes by this syntax: ${VARIABLE:-default}.

The whole thing has to be thought in such a way that this "default" value is something distinct from a "valid" value/content.

If that's not possible for some reason you probably need to add a step like checking if there's a value at all, along the lines of "if [ -z $VARIABLE ] ; then echo "the variable needs to be filled"", or "if [ ! -z $VARIABLE ] ; then #everything is fine, proceed with the rest of the script".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJordanss10View Question on Stackoverflow
Solution 1 - BashriciView Answer on Stackoverflow
Solution 2 - BashJuha VehniaView Answer on Stackoverflow
Solution 3 - BashyileeView Answer on Stackoverflow
Solution 4 - BashStuart CardallView Answer on Stackoverflow
Solution 5 - Bashel guestoView Answer on Stackoverflow