Avoiding Unexpected Token Errors in Bash

Photo by Andrew Neel on Unsplash

Avoiding Unexpected Token Errors in Bash

·

4 min read

Most of the time, the answer is staring right at us and at times, you can't seem to just get hold of the error when there seems nothing wrong with it. Right?

Let me share a few examples of "Unexpected token" errors that I have been breaking my head with recently.

This is a test.sh with a simple check, if the a==5 echo "yes".

$ cat test.sh
a=$1
if [$a == 5] then
        echo 'yes'
fi

When I try executing it, I see the below error:

$ ./test.sh
./test.sh: line 4: syntax error near unexpected token `fi'
./test.sh: line 4: `fi'

It is very easier to forget that $1 is expected to be fed as a value for a, even after I corrected that, the error persisted. So, the issue wasn't just with $1, something else was off.

$ ./test.sh 7
./test.sh: line 4: syntax error near unexpected token `fi'
./test.sh: line 4: `fi'

A few mistakes were to be fixed:

a=$1 
## Use appropriate spaces between the variable and braces
if [ $a == 5 ]; then # add ; to if before then
        echo 'yes'
fi
$ ./test.sh 5
yes

Finally, to get it working properly, I modified the code a little bit to echo the usage for the script, and condition set for else to know what happens when a non-5 number is passed.

echo "Usage ./test <num>"
a=$1
if [ "$a" -eq 5 ]; then  # since it was check for equal, I used -eq 
    echo "yes"
else
   echo "Not 5"
fi

Thanks to one of the StackOverflow answers, I happened to learn about ShellCheck – shell script analysis tool.

I was still not fully set with the script, as the checker pointed out, it didn't have a reference to the shell directive.

After adding that, the checker seems to be happy and passed my script with "no issues found"

But guess what, after the debugging journey - comes the realization of how less I've known. I looked up [linux - Difference between [[ ]] AND [ ] or (( )) AND ( ) in Bash - Super User](superuser.com/questions/1533900/difference-..). I always thought [[]] is used for every operation irrespective. Sometimes, it is the lack of awareness, but we should try going that extra mile to look for better alternatives or rather effective ones than just getting a broken code working.

Let's take this another example,

for item in $(cat items.txt); do
    echo "The fruit I see now: $item"
    if [[ $item == "apple" ]]; then
       echo "It is my favorite fruit!"
    else if [[ $item == "banana" ]]; then
       echo "That is my pet's favorite fruit!"
    else
       echo "This might be something I like in a salad!"
    fi
done

When I execute the above code, I run into my old 'unexpected token' friend, yet again, I am trying to think hard, what could be wrong here?

$ ./test.sh
./test.sh: line 10: syntax error near unexpected token `done'
./test.sh: line 10: `done

My simple ignorance was to use else if, instead of elif, after fixing that, it worked like a charm,

for item in $(cat items.txt); do
    if [[ $item == "apple" ]]; then
       echo "$item is my favorite fruit!"
    elif [[ $item == "banana" ]]; then
       echo "$item is my pet's favorite fruit!"
    else
       echo "$item might be something I like in a salad!"
    fi
done
$ ./test.sh
apple is my favorite fruit!
orange might be something I like in a salad!
mango might be something I like in a salad!
grapes might be something I like in a salad!
banana is my pet's favorite fruit

going back to basics is one other key thing we shouldn't hesitate to do. Time to time, works wonders, exploring more scenarios could fast-track that process for you. You don't necessarily have to remember it all but keeping a bunch of bookmarks for syntax checking could help you in long run.

That's it from me for now, good day!