Analysis and Fix for 'syntax error near unexpected token 'fi'' in Bash Scripts

Nov 28, 2025 · Programming · 11 views · 7.8

Keywords: Bash syntax error | if statement repair | shell script debugging

Abstract: This article provides an in-depth analysis of the common 'syntax error near unexpected token 'fi'' error in Bash scripts. Through detailed code examples, it explains the root causes and provides comprehensive solutions. Starting from Bash syntax rules, the article covers proper if statement formatting, the importance of spaces in conditional tests, variable handling techniques, and complete repair strategies. Additionally, it extends the discussion to Bash conditional statement parsing mechanisms and best practices based on reference materials, helping readers fundamentally avoid similar syntax errors.

Error Phenomenon and Code Analysis

In Bash script development, syntax errors are common issues. A user reported encountering a "syntax error near unexpected token 'fi'" error while executing a script to remove .jpg files ending with odd numbers. Let's first analyze the original code:

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if[$((fname %  2)) -eq 1 ] then
    echo "removing $fname\n"
    rm $f
  fi
done

Deep Analysis of Error Causes

After careful analysis, the script contains multiple syntax issues:

First, the if statement format is incorrect. In Bash, if statements require specific syntax structures. When the then keyword is on the same line as the conditional test, a semicolon must be used as a separator; alternatively, then can be placed on a new line. The original code if[$((fname % 2)) -eq 1 ] then lacks the necessary separator.

Second, space handling in conditional tests is improper. In Bash, [ is actually a command (usually an alias for the test command), so it requires spaces before and after the command name, just like other commands. The original code if[$((fname % 2)) -eq 1 ] lacks spaces around [.

Additionally, there is variable name inconsistency: fname="${filename%.*}" should use fname instead of filename.

Repair Solution and Complete Code

Based on the above analysis, we provide a complete repair solution:

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${fname%.*}"
  echo "fname is $fname\n"
  if [ $((fname % 2)) -eq 1 ]
  then
    echo "removing $fname\n"
    rm "$f"
  fi
done

Key modifications include:

Bash Conditional Statement Parsing Mechanism

According to the in-depth analysis from reference materials, keywords like if, then, else, fi in Bash need to appear in positions where the shell expects command names; otherwise, they are treated as ordinary words.

In conditional statements like if [ condition ] then, if proper separators are missing, then will be parsed as an argument to the [ command rather than as a keyword of the conditional statement. The shell continues to look for the then keyword, and when it encounters fi, since there's still an unfinished if statement waiting for then, the appearance of fi is "unexpected," resulting in a syntax error.

Best Practice Recommendations

To avoid similar syntax errors, it is recommended to:

By understanding Bash's parsing mechanisms and following correct syntax rules, you can effectively avoid "syntax error near unexpected token" type errors and write more robust shell scripts.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.