Real‑world examples of examples of shell script syntax errors
Let’s start with a few quick examples of shell script syntax errors you’re likely to see in real logs and CI pipelines. These are the best examples because they’re short, painful, and very common.
Missing then in an if statement
#!/usr/bin/env bash
if [ "$USER" = "root" ]
echo "Running as root"
fi
Typical error:
./script.sh: line 4: syntax error near unexpected token `echo'
./script.sh: line 4: ` echo "Running as root"'
The shell expected then after the if condition. Adding it fixes the script:
if [ "$USER" = "root" ]; then
echo "Running as root"
fi
Unclosed quote
echo "This line never ends
Error:
> # shell waits for closing quote, no prompt return
The shell treats everything after the first quote as part of the same string. Close the quote or escape the newline.
These tiny snippets are just the appetizer. The rest of this article walks through richer, real examples of examples of shell script syntax errors, why they happen, and how to avoid them.
Classic example of broken if and for syntax
When people search for examples of examples of shell script syntax errors, broken conditionals and loops sit at the top of the list. They look “almost right” to a human, but the shell is very picky about where keywords go.
Broken if / elif / else layout
Consider this script that tries to categorize a number:
#!/usr/bin/env bash
num=$1
if [ "$num" -lt 0 ]
echo "negative"
elif [ "$num" -eq 0 ]
echo "zero"
else
echo "positive"
fi
On a modern Bash, you’ll see something like:
./sign.sh: line 5: syntax error near unexpected token `elif'
./sign.sh: line 5: `elif [ "$num" -eq 0 ]'
The shell never saw a then after the first if, so by the time it reaches elif, it’s already confused.
Fixed version:
if [ "$num" -lt 0 ]; then
echo "negative"
elif [ "$num" -eq 0 ]; then
echo "zero"
else
echo "positive"
fi
Misplaced do in a for loop
Another classic example of shell script syntax errors shows up in quick one‑off scripts:
for file in *.log
echo "Processing $file"
gzip "$file"
done
Error:
./compress.sh: line 3: syntax error near unexpected token `echo'
./compress.sh: line 3: ` echo "Processing $file"'
The shell expects a do keyword before the loop body:
for file in *.log; do
echo "Processing $file"
gzip "$file"
done
These are simple, but they’re the best examples to memorize because they catch a huge percentage of everyday mistakes.
Real examples of quoting and variable expansion mistakes
If/then errors are loud. Quoting errors are sneakier. Many real examples of shell script syntax errors start as quoting problems that morph into syntax problems when spaces or special characters appear.
Unquoted variables turning into syntax errors
Imagine a deployment script:
#!/usr/bin/env bash
env_name=$1
if [ $env_name = production ]; then
echo "Deploying to prod"
fi
This might work in tests, then randomly fail in CI with:
./deploy.sh: line 5: [: too many arguments
Now try calling it with an argument that includes a space:
./deploy.sh "staging us-east-1"
The shell expands $env_name into multiple words, which breaks the [ test syntax. The fix is to quote variables almost by default:
if [ "$env_name" = "production" ]; then
echo "Deploying to prod"
fi
While this is technically a logic error more than a raw syntax error, it’s often reported as a syntax problem by the [ built‑in, so it belongs in any list of real examples of shell script syntax errors.
Mixed quotes and unescaped $ or backticks
Here’s another example of shell script syntax errors that show up when people mix double quotes, single quotes, and command substitution:
#!/usr/bin/env bash
msg='User is $USER and date is `date`'
echo "$msg"
This runs, but it doesn’t behave as intended. The variables don’t expand because they’re in single quotes. People then try to “fix” it like this:
msg='User is \(USER and date is \)(date)'
Still wrong for the same reason. The correct pattern is to use double quotes when you want expansion:
msg="User is \(USER and date is \)(date)"
Now imagine a more subtle variation:
msg="Path is $HOME and last command was `history | tail -1`"
If you forget the closing backtick or quote, you’ll get a syntax error that points several lines later, which makes debugging painful. These are the kinds of examples of examples of shell script syntax errors that waste the most time in large scripts.
Examples include bad shebangs and shell portability problems
A trend that’s become more obvious in 2024–2025: people write Bash‑specific syntax, then run the script under /bin/sh in containers or CI images that use a stricter shell like dash.
Bash arrays in /bin/sh
#!/bin/sh
servers=(api1 api2 api3)
for s in "${servers[@]}"; do
echo "Pinging $s"
ping -c1 "$s"
done
On Debian/Ubuntu (where /bin/sh is dash), you’ll see:
./ping.sh: 4: Syntax error: "(" unexpected
The array syntax servers=(...) is not POSIX‑sh; it’s Bash. There are two fixes:
Use a Bash shebang:
#!/usr/bin/env bashOr rewrite using POSIX‑compatible syntax:
servers="api1 api2 api3" for s in $servers; do echo "Pinging $s" ping -c1 "$s" done
This is one of the best examples of how syntax errors can be environment‑dependent. The exact same file works fine on a developer laptop and explodes in a minimal container.
[[ tests in non‑Bash shells
Another portability trap:
#!/bin/sh
if [[ -f /etc/passwd ]]; then
echo "Found passwd file"
fi
Error under dash:
./check.sh: 4: [[: not found
Some shells treat [[ as a command name, not syntax, and complain. Again, either switch to a Bash shebang or use POSIX [:
#!/bin/sh
if [ -f /etc/passwd ]; then
echo "Found passwd file"
fi
These portability issues are great real examples of shell script syntax errors that only show up when you move from one environment to another.
Pipeline and here‑document examples of subtle syntax errors
Once scripts grow beyond a few lines, pipelines and here‑documents start to appear. They’re powerful, but they also provide rich examples of examples of shell script syntax errors.
Trailing pipe in a multi‑line pipeline
Consider a log‑processing script:
#!/usr/bin/env bash
grep "ERROR" app.log |
cut -d' ' -f1,2 |
sort |
uniq -c |
The last line ends with a |. Bash reports:
./logs.sh: line 7: syntax error near unexpected token `newline'
./logs.sh: line 7: ` uniq -c |'
The shell is expecting another command after the final pipe. Remove the trailing | or add the next command:
uniq -c
This is a tiny typo but a very common example of shell script syntax errors in long pipelines.
Mis‑indented or unterminated here‑document
Here‑documents (<<EOF) are another source of syntax surprises:
#!/usr/bin/env bash
cat <<EOF
User: $USER
Home: $HOME
EOF
echo "Done"
If the EOF marker is indented or has trailing spaces, the shell may treat it as plain text and keep looking for the end of the here‑document. The script then runs into the echo line in a weird state and throws a syntax error much later than the real bug.
To avoid this, keep the delimiter at the start of the line with no extra characters, or use <<-EOF with tabs only.
2024–2025: CI, containers, and linting tools
Modern workflows have changed where we see the best examples of shell script syntax errors:
- CI pipelines (GitHub Actions, GitLab CI, Jenkins) run scripts under bare‑bones shells, which expose missing dependencies and strict syntax.
- Containers often use
/bin/shlinked todashorbusybox, which reject non‑POSIX syntax that Bash tolerated. - Linting tools like
shellcheckcatch many syntax issues before runtime.
One of the most useful real examples from CI logs looks like this:
- name: Run deployment script
run: ./deploy.sh
And the log shows:
./deploy.sh: line 12: syntax error near unexpected token `then'
./deploy.sh: line 12: ` then'
Error: Process completed with exit code 2.
When you inspect the script, you find something like:
if [ "$BRANCH" = "main" ]
then
deploy
fi
Some shells allow the then on the next line, but only if the previous line ends with ;. The portable pattern is:
if [ "$BRANCH" = "main" ]; then
deploy
fi
To keep up with these trends, many teams now:
- Add
shellcheckto CI for all.shfiles. - Standardize on
#!/usr/bin/env bashor strict POSIX/bin/shand stick to it. - Treat syntax errors as test failures, not “we’ll fix it later.”
The ShellCheck wiki provides detailed explanations of many of these patterns and is a good companion reference when you want more examples of shell script syntax errors and their fixes.
Practical debugging tips using these examples
Now that we’ve walked through several examples of examples of shell script syntax errors, let’s talk about how to debug them efficiently.
Read the line before the error
Shell error messages often point to the line where the parser finally gave up, not where the mistake started. If you see:
line 27: syntax error near unexpected token `else'
check line 26 carefully for missing then, ;, or }. Many of the best examples above follow this pattern: the real bug lives just above the reported line.
Use set -x and bash -n
Two built‑in tools help a lot:
bash -n script.shchecks for syntax errors without running the script.set -xprints each command as it executes, which helps you see where parsing went wrong.
Combine them with linting tools like ShellCheck for a much smoother experience. While ShellCheck is not a government or medical authority, it plays a similar role for shell scripts that sites like Harvard or NIH play for education and health information: a reliable reference you can keep coming back to.
FAQ: common questions and more examples
What are some everyday examples of shell script syntax errors?
Everyday examples include missing then in if statements, missing do in loops, unclosed quotes, trailing | in pipelines, using Bash arrays under /bin/sh, and mixing [[ with non‑Bash shells. The code snippets earlier in this article show each example of these patterns with both the error message and the corrected version.
How do I quickly find the line causing the syntax error?
Start with the line number in the error message, then inspect that line and the line before it. Run bash -n script.sh to confirm the error location. If the file is long, comment out chunks until the syntax error disappears, then narrow down. Many real examples of shell script syntax errors end up being a single missing quote or semicolon.
Is it better to use /bin/sh or Bash to avoid syntax issues?
If you need maximum portability (embedded systems, minimal containers), write POSIX‑sh scripts and use /bin/sh. If you control the environment and want more features, use Bash and a Bash shebang. The important part is to align your syntax with your shebang; many examples of examples of shell script syntax errors come from mixing Bash features with /bin/sh.
Can tools automatically detect these syntax errors?
Yes. bash -n and sh -n perform syntax checks without executing the script. Static analyzers like ShellCheck go further and warn about quoting issues, unportable constructs, and potential logic bugs. Integrating these tools into CI is one of the best examples of low‑effort, high‑value improvements for shell scripting.
If you keep these real examples in mind—missing keywords, quoting mistakes, portability traps, and pipeline quirks—you’ll recognize the patterns instantly the next time your script explodes with a “syntax error near unexpected token” message. And that’s the point: not to avoid every mistake, but to shorten the time between “it broke” and “oh, I know exactly what this is.”
Related Topics
Explore More Syntax Errors
Discover more examples and insights in this category.
View All Syntax Errors