Fix Bash Syntax Error Near Unexpected Token — Real Fixes
This error pops up when bash finds a character it didn't expect. Usually a missing quote, bracket, or a typo in a script. Here's how to spot and fix the three most common causes.
1. Missing Quote or Mismatched Quote
This is the #1 cause I see. You start a string with a single quote but forget to close it — or you use a double quote inside a single-quoted string. Bash gets confused and throws the error at the next line.
Real example: Had a client last month who copied a command from a web page with a curly single quote instead of a straight one. Bash saw the start quote but never saw the end. Error showed on the next command, not the broken line.
How to spot it: Look at the line before the error. Is there a quote that doesn't match? Run your script with bash -n script.sh — it parses the script without running it and points to the line number of the first problem. Skip the GUI editors sometimes — use cat -A script.sh to show hidden characters like weird spaces or carriage returns.
Fix: Check for:
- Missing closing quote:
echo 'helloshould beecho 'hello' - Mixed quote types:
echo "It's fine"is okay, butecho 'It's fine'breaks. - Use
grep -n '"' script.shto find lines with double quotes — then count them.
2. Dangling Pipe or Redirection
You put a pipe | at the end of a line, but the next line doesn't continue the command. Or you redirect to a file and miss the filename. Bash sees the pipe and expects something after it — if the next line is blank or a comment, it throws the error at the pipe's line.
Real scenario: A sysadmin at a coffee shop chain ran a backup script that had a pipe after a grep command, then a blank line. The error showed up after the blank line, making it confusing. Took me 5 minutes to spot the trailing pipe.
How to spot it: Scan lines ending with |, >, >>, <. Use grep -n '|\(
\)' script.sh — but honestly, just look at the error line and the one before it. The pipe line is often the culprit.
Fix: Remove the trailing pipe, or make sure the next line starts with a command that completes it. If you want to break a command across lines, use a backslash \ after the pipe. Example:
# Bad — breaks
cat file |
grep 'error'
# Good — continues
cat file | \
grep 'error'
Also check for redirections missing targets: echo hello > should be echo hello > output.txt.
3. Mismatched Brackets or Parentheses
Bash uses (), {}, [], <() for different things. If you open one and don't close it, or you close with the wrong one, you get the error. This is common in if statements or for loops.
Real example: A developer wrote a script with nested if statements. Used a closing } instead of fi. The error pointed to the line after the if block, not inside it. Confused him for an hour.
How to spot it: Count brackets. grep -o '[' script.sh | wc -l and grep -o ']' script.sh | wc -l should match. Same for {} and (). For parentheses inside $(), make sure they're balanced — $(echo hello needs a closing ).
Fix: Use a code editor with syntax highlighting, or run bash -x script.sh to trace execution. It shows each line before running it — you'll see the broken line right before the error. For if statements, remember the pattern:
if [ condition ]; then
commands
fi
Don't use {} in place of fi. Also check case statements — each case ends with ;;, and the whole thing ends with esac.
Quick-Reference Summary Table
| Cause | Symptom | Fix |
|---|---|---|
| Missing quote | Error on line after the quote | Check quote pairs, use bash -n |
| Dangling pipe / redirection | Error on the pipe line | Remove trailing pipe, add backslash for multi-line |
| Mismatched bracket / parentheses | Error near the bracket | Count brackets, use bash -x to trace |
Most of the time, it's a simple typo. Don't overthink it. Check the line before the error first, then the error line itself. Use bash -n and cat -A to see what's really there. I've fixed hundreds of these — 90% are quote or pipe issues. Good luck.
Was this solution helpful?