Bash syntax error: unexpected end of file
Asked Answered
A

24

158

Forgive me for this is a very simple script in Bash. Here's the code:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

after running sh file.sh:

syntax error: unexpected end of file

Agiotage answered 16/6, 2011 at 2:34 Comment(0)
N
187

I think file.sh is with CRLF line terminators.

run

dos2unix file.sh

then the problem will be fixed.

You can install dos2unix in ubuntu with this:

sudo apt-get install dos2unix
Noenoel answered 16/6, 2011 at 2:50 Comment(7)
Whats the reason behind this problem? I usually work on Windows but need to transfer scripts to unix systems.Viki
Newline in windows is "\r\n", while in linux is "\n".Noenoel
@KeesdeKooter I wouldn't say just because something didn't work for you that you should downvote it, clearly it worked for the 28 upvotes. A simple it didn't work for me suffices. That's why SO allowed multiple answers to a question because there can be multiple solutions to a problem.Jaye
Using notepad++ editor Edit>EOL Conversion>Old Mac Format solved it for me.Sarcoid
If you can Edit your bash file with Notepad++. Go to Edit-> EOL Conversion-> Macintosh(CR). Change it to Macintosh(CR) even if you are using Windows OS.Whalebone
Before installing maybe try (in vim) ':set fileformat=unix'. This worked for me in the Windows Subsystem for Linux (WSL).Tremble
@Viki — the problem arises because Bash treats then\r as a command name, and fi\r as another, and then thinks that it has not seen the correct format for an if …; then …; fi statement — so it reports 'unexpected EOF'.Sheela
A
183

Another thing to check (just occured to me):

  • terminate bodies of single-line functions with semicolon

I.e. this innocent-looking snippet will cause the same error:

die () { test -n "$@" && echo "$@"; exit 1 }

To make the dumb parser happy:

die () { test -n "$@" && echo "$@"; exit 1; }
Absurdity answered 8/7, 2014 at 15:37 Comment(3)
+1 Also applies to code snippets with brackets like so: [[ "$#" == 1 ]] && [[ "$arg" == [1,2,3,4] ]] && printf "%s\n" "blah" || { printf "%s\n" "blahblah"; usage; } ............ Note that semicolon inside the squiggly brackets, just after calling some previously defined function 'usage'. Forgetting that will get you the same syntax error: unexpected eof.Hols
you nailed it. Actually the simple thing is the ; Every statement is being expected to end with ; so put that at the end eg: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi will produce that error, whereas if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi; will not... notice the little semi-colons at the end, ie: after .bash and fi.Worthington
I had this in a script shared with me from a zsh user. The former does work in zsh but not in sh nor bash. Wish I was 4 people so I could give this 4 upvotesKaleighkalends
R
77

i also just got this error message by using the wrong syntax in an if clause

  • else if (syntax error: unexpected end of file)
  • elif (correct syntax)

i debugged it by commenting bits out until it worked

Rex answered 26/11, 2015 at 13:36 Comment(2)
Thank you soo much.. someone please give this guy a medalSquireen
After installing dos2unix and finding it didn't fix my issue scrolled down to this answer. Strange thing was gedit was highlighting my else if as valid syntax so I was assuming it was valid usage.Liddy
R
38

an un-closed if => fi clause will raise this as well

tip: use trap to debug, if your script is huge...

e.g.

set -x
trap read debug
Recurved answered 28/8, 2017 at 1:0 Comment(6)
I exactly forgot the "fi"! Thanks :) If you could, for the benefit of everyone, elaborate a bit on your tip of using trap.Bandaid
sorry for the delay, my friend. 'the 'trap' command is a way to debug your scripts by esentially breaking after every line. a fuller discussion is here: #9080931Recurved
That was useful thanks a lot. Note that the unexpected end of file error will occur as soon as the fi is hit.Photochronograph
Ah so, one should not write those set and trap commands into the actual script, as it says in that post you suggested might clarify your answer? You write it in the shell, and then call the script. Please do clarify, save everyone running round in circles.Trillby
@Markling - I anticipate folks would take the traps out after they have debugged their script.Recurved
That is, if they are advised well enough that they know what a trap is, and where and how they should put it!Trillby
T
17

I got this answer from this similar problem on StackOverflow

Open the file in Vim and try

:set fileformat=unix

Convert eh line endings to unix endings and see if that solves the issue. If editing in Vim, enter the command :set fileformat=unix and save the file. Several other editors have the ability to convert line endings, such as Notepad++ or Atom

Thanks @lemongrassnginger

Tremble answered 12/3, 2018 at 1:25 Comment(1)
These are just alternative ways to do dos2unix as the accepted answer advises.Absurdity
Q
13

I had the problem when I wrote "if - fi" statement in one line:

if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi

Write multiline solved my problem:

if [ -f ~/.git-completion.bash ]; then 
    . ~/.git-completion.bash
 fi
Quadrifid answered 28/8, 2018 at 7:16 Comment(1)
You can also keep it as one line like this: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi (note the ; near the end).Smolt
P
12

This was happening for me when I was trying to call a function using parens, e.g.

run() {
  echo hello
}

run()

should be:

run() {
  echo hello
}

run
Premedical answered 7/5, 2019 at 6:50 Comment(1)
Thank you!! It was just my problem, I thought it was related to the other answers.Minneapolis
I
8

So I found this post and the answers did not help me but i was able to figure out why it gave me the error. I had a

cat > temp.txt < EOF
some content
EOF

The issue was that i copied the above code to be in a function and inadvertently tabbed the code. Need to make sure the last EOF is not tabbed.

Indecorous answered 23/8, 2016 at 19:49 Comment(1)
This was exactly my case. I had EOF indented by four spaces and bash didn't parse it because of that. Removing spaces fixed the issue.Atalie
C
7

on cygwin I needed:-

 export SHELLOPTS
 set -o igncr

in .bash_profile . This way I didn't need to run unix2dos

Cullin answered 17/6, 2013 at 10:14 Comment(0)
W
5

FOR WINDOWS:

In my case, I was working on Windows OS and I got the same error while running autoconf.

  • I simply open configure.ac file with my NOTEPAD++ IDE.
  • Then I converted the File with EOL conversion into Windows (CR LF) as follows:

    EDIT -> EOL CONVERSION -> WINDOWS (CR LF)

Whalebone answered 20/6, 2019 at 20:13 Comment(1)
Thank you, that did it for me. I use OpenShift s2i nginxKingcraft
D
4

Missing a closing brace on a function definition will cause this error as I just discovered.

function whoIsAnIidiot() {
    echo "you are for forgetting the closing brace just below this line !"

Which of course should be like this...

function whoIsAnIidiot() {
    echo "not you for sure"
}
Dogwatch answered 29/6, 2020 at 17:16 Comment(0)
W
3

For those who don't have dos2unix installed (and don't want to install it):

Remove trailing \r character that causes this error:

sed -i 's/\r$//' filename

Details from this StackOverflow answer. This was really helpful. https://mcmap.net/q/20384/-39-r-39-command-not-found-bashrc-bash_profile-duplicate

Woodsy answered 18/11, 2021 at 11:2 Comment(0)
E
2

I was able to cut and paste your code into a file and it ran correctly. If you execute it like this it should work:

Your "file.sh":

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

The command:

$ ./file.sh arg1 arg2 arg3

Note that "file.sh" must be executable:

$ chmod +x file.sh

You may be getting that error b/c of how you're doing input (w/ a pipe, carrot, etc.). You could also try splitting the condition into two:

if [ $# -lt 3 ] || [ $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Or, since you're using bash, you could use built-in syntax:

if [[ $# -lt 3 || $# -gt 3 ]]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

And, finally, you could of course just check if 3 arguments were given (clean, maintains POSIX shell compatibility):

if [ $# -ne 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi
Erb answered 16/6, 2011 at 2:39 Comment(2)
i still got the same error. im not exactly sure where the code goes wrongAgiotage
weird, i cut and pasted your code and it worked as expected. was there any more error output? a lot of time bash will list a line number. also, what system are you running? (Linux, MacOS, BSD, distro, etc)Erb
B
2

In my case, there is a redundant \ in the like following:

function foo() {
    python tools/run_net.py \
                           --cfg configs/Kinetics/X3D_8x8_R50.yaml \
                           NUM_GPUS 1 \
                           TRAIN.BATCH_SIZE 8 \
                           SOLVER.BASE_LR 0.0125 \
                           DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
                           DATA.PATH_PREFIX  ./afs/kinetics400  \  # Error
}

There is NOT a \ at the end of DATA.PATH_PREFIX ./afs/kinetics400

Boehmer answered 12/7, 2020 at 2:27 Comment(0)
I
1

Apparently, some versions of the shell can also emit this message when the final line of your script lacks a newline.

Iciness answered 21/9, 2016 at 3:17 Comment(0)
A
0

I just cut-and-pasted your example into a file; it ran fine under bash. I don't see any problems with it.

For good measure you may want to ensure it ends with a newline, though bash shouldn't care. (It runs for me both with and without the final newline.)

You'll sometimes see strange errors if you've accidentally embedded a control character in the file. Since it's a short script, try creating a new script by pasting it from your question here on StackOverflow, or by simply re-typing it.

What version of bash are you using? (bash --version)

Good luck!

Apteral answered 16/6, 2011 at 2:47 Comment(0)
R
0

Make sure the name of the directory in which the .sh file is present does not have a space character. e.g: Say if it is in a folder called 'New Folder', you're bound to come across the error that you've cited. Instead just name it as 'New_Folder'. I hope this helps.

Ruin answered 3/2, 2016 at 4:44 Comment(0)
S
0

In Ubuntu:

$ gedit ~/.profile

Then, File -> Save as and set end line to Unix/Linux

Susanasusanetta answered 13/3, 2018 at 8:12 Comment(0)
R
0

I know I am too late to the party. Hope this may help someone.

Check your .bashrc file. Perhaps rename or move it.

Discussion here: Unable to source a simple bash script

Roden answered 19/4, 2019 at 17:9 Comment(0)
G
0

For people using MacOS:

If you received a file with Windows format and wanted to run on MacOS and seeing this error, run these commands.

brew install dos2unix
sh <file.sh>
Galcha answered 18/7, 2019 at 22:15 Comment(5)
this seems to me like installing dos2unix utility then not using itCipolin
dos2unix is used internally when you run sh to parse the .sh file.Galcha
oh wow, by what? Does Homebrew wrap sh with a dos2unix piping wrapper script?Cipolin
I'll dare to say by pure guess that Homebrew doesn't do it. Moreover, if it does, it'd be good not to rely on that.Cipolin
Also, Homebrew is not preinstalled out of the box on macOS last time I heard, so it's important to note thatCipolin
U
0

If the the script itself is valid and there are no syntax errors, then some possible causes could be:

  • Invalid end-of-lines (for example, \r\n instead of \n)
  • Presence of the byte order mark (BOM) at the beginning of the file

Both can be fixed using vim or vi.

To fix line endings open the file in vim and from the command mode type:

:set ff=unix

To remove the BOM use:

:set nobomb
Unmuzzle answered 21/8, 2021 at 16:13 Comment(0)
B
0

If you're using vscode you can create a .editorconfig file and put this in it:

[*.sh]
end_of_line = cr

then save your bash files again, as far as I understood when you save a file vscode by default uses crlf as end of line to present line breaks.

Blume answered 3/6, 2023 at 17:45 Comment(0)
U
0

I found @Juniar 's answer very helpful https://mcmap.net/q/150589/-bash-syntax-error-unexpected-end-of-file

Mine was originally set as Windows(CR LF) and reported error; when I changed it to Unix (LF), it worked!

Unpeopled answered 11/6, 2023 at 15:47 Comment(0)
S
0

Problem comes from EOL in differences OS EOL

I resolve this problem with below steps

Step 1: If you using Notepad++ in windows please add end line at end of file (*) with Enter keyboard

Step 2: In Notepad++ Edit> EOL conversion -> Unix (LF)

Step 3: Save the file with any named you want (exp: test.sh), after that using the file in Unix OS

Step 4: Running the basg file with command "bash test.sh"

Thank you @tensom for your answer

echo  "###  ABC START  ###"
pid= "abc"
if [ ${pid} != "" ]
then
  echo "a running"
else
  echo "a not running"
fi (*)
Spavined answered 19/1 at 8:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.