Below I have a shell script i wrote and when I try to execute it I get an error in my terminal describing the "expecting fi" keyword. I have written it down before the done keyword and have still not managed to overcome to error. Can anybody tell me as to how to solve this error and where in my approach I have made the mistake?
VAL1=0 VAL2=0 while [ "$VAL1" -eq 0 ] && [ "$VAL2" -eq 0 ] do read -p "Enter values for both numbers" VAL1 VAL2 if [ "$VAL1" -eq 99 ] || [ "$VAL1" -eq 99 ] then break else read -p "Enter value number two" VAL2 if [ "$VAL2" -eq 0 ] then echo "Cannot divide by zero" else echo $(( VAL1 / VAL2 )) fi done 1 2 Answers
“Expecting fi” means your script is missing this keyword. In your case you have two ifs, but only one fi, leaving the first unclosed. Correct it to:
else echo $(( VAL1 / VAL2 )) fi fi
doneIn order to debug shell scripts it’s a good idea to use shellcheck either online or via the command shellcheck (sudo apt install shellcheck):
$ shellcheck myscript
Line 4: while [ "$VAL1" -eq 0 ] && [ "$VAL2" -eq 0 ] ^-- SC1009: The mentioned syntax error was in this while loop.
Line 6: if [ "$VAL1" -eq 99 ] || [ "$VAL1" -eq 99 ] ^-- SC1046: Couldn't find 'fi' for this 'if'. ^-- SC1073: Couldn't parse this if expression. Fix to allow more checks.
Line 13: done ^-- SC1047: Expected 'fi' matching previously mentioned 'if'. ^-- SC1072: Unexpected keyword/token. Fix any mentioned problems and try again. As dessert already pointed out, having two ifs but only one fi immediately tells you that there is a mismatch somewhere in your conditional statement.
One thing I would suggest is that when coding, it helps to use your indentation to help figure out if you are missing any structure. Keeping your if-then-else-fi within the same column is one trick that can be used to keep track of these things. Same for the case-esac or the do-done for that matter.
Using your sample code, if we indent in that manner, it's pretty clear with regards to something missing:
VAL1=0
VAL2=0
while [ "$VAL1" -eq 0 ] && [ "$VAL2" -eq 0 ]
do read -p "Enter values for both numbers" VAL1 if [ "$VAL1" -eq 99 ] || [ "$VAL1" -eq 99 ] then break else read -p "Enter value number two" VAL2 if [ "$VAL2" -eq 0 ] then echo "Cannot divide by zero" else echo $(( VAL1 / VAL2 )) fi ?? <------ *Missing fi would likely have been detected here*
done