/errors/bash/syntax-error-near-unexpected-token
bash: syntax error near unexpected token
- tool
- Bash
- exit code
- 2
- versions
- bash 4.x – 5.x
- os
- linux, macos, windows
syntax error near unexpected token means bash's parser hit a word or symbol that is not allowed at that position, so it refused to run the script. The token in backquotes is where parsing failed; the real mistake is usually just before it (a missing then, do or ;, or an unquoted parenthesis). Scripts edited on Windows often fail this way because of CRLF line endings.
Reproduce it
printf 'if [ -f /etc/hostname ]\necho found\nfi\n' > missing_then.sh
bash missing_then.shOutput · exit 2
missing_then.sh: line 3: syntax error near unexpected token `fi' missing_then.sh: line 3: `fi'
then is missing, so bash reaches fi while it still expects the then part. The exit status of a syntax error is 2.
Unquoted parentheses
echo 'echo Total (incl. tax)' > parens.sh
bash parens.shOutput · exit 2
parens.sh: line 1: syntax error near unexpected token `('
parens.sh: line 1: `echo Total (incl. tax)'( starts a subshell in bash. Quote the text: echo 'Total (incl. tax)'.
Windows line endings (CRLF)
A script saved with CRLF line endings has an invisible carriage return (\r, shown by bash as $'\r') at the end of every line. On Linux and macOS bash reads it as part of the word, so do, then or { is not recognised as a keyword and the script fails with this error or with $'\r': command not found. Git Bash on Windows tolerates CRLF scripts, which is why a script can work locally and fail in a Linux CI job. Count and strip the carriage returns:
printf 'for f in a b; do\r\n echo "$f"\r\ndone\r\n' > crlf.sh
printf 'carriage returns: %s\n' "$(tr -cd '\r' < crlf.sh | wc -c)"
tr -d '\r' < crlf.sh > lf.sh
printf 'carriage returns: %s\n' "$(tr -cd '\r' < lf.sh | wc -c)"
bash lf.shOutput
carriage returns: 3 carriage returns: 0 a b
dos2unix script.sh (or sed -i 's/\r$//' script.sh with GNU sed on Linux) converts the file in place. In Git, a .gitattributes line *.sh text eol=lf keeps shell scripts LF on every platform (see core.autocrlf).
Check without running
printf 'while true\necho loop\ndone\n' > loop.sh
bash -n loop.shOutput · exit 2
loop.sh: line 3: syntax error near unexpected token `done' loop.sh: line 3: `done'
bash -n parses the file and reports syntax errors without executing anything. ShellCheck explains many of these errors in more detail.