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!