Меню

Синтаксическая ошибка неожиданный конец файла bash

You are running a Bash script, and you see a syntax error: Unexpected end of file.

What does it mean?

This can happen if you create your script using Windows.

Why?

Because Windows uses a combination of two characters, Carriage Return and Line Feed, as line break in text files (also known as CRLF).

On the other side Unix (or Linux) only use the Line Feed character as line break.

So, let’s see what happens if we save a script using Windows and then we execute it in Linux.

Using the Windows notepad I have created a Bash script called end_of_file.sh:

#/bin/bash

if [ $# -gt 0 ]; then
  echo "More than one argument passed"
else
  echo "No arguments passed"
fi

And here is the output I get when I execute it:

[ec2-user@localhost scripts]$ ./end_of_file.sh 
./end_of_file.sh: line 2: $'r': command not found
./end_of_file.sh: line 8: syntax error: unexpected end of file 

How do we see where the problem is?

Edit the script with the vim editor using the -b flag that runs the editor in binary mode:

[ec2-user@localhost scripts]$ vim -b end_of_file.sh

(Below you can see the content of the script)

#/bin/bash^M
^M
if [ $# -gt 0 ]; then^M
  echo "More than one argument passed"^M
else^M
  echo "No arguments passed"^M
fi^M

At the end of each line we see the ^M character. What is that?

It’s the carriage return we have mentioned before. Used by Windows but not by Unix (Linux) in line breaks.

To solve both errors we need to convert our script into a format that Linux understands.

The most common tool to do that is called dos2unix.

If dos2unix is not present on your system you can use the package manager of your distribution to install it.

For instance, on my server I can use YUM (Yellowdog Updater Modified).

To search for the package I use the yum search command:

[root@localhost ~]$ yum search dos2unix
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
====================== N/S matched: dos2unix =====================================
dos2unix.x86_64 : Text file format converters

And then the yum install command to install it:

[root@localhost ~]$ yum install dos2unix
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                   | 2.4 kB  00:00:00
amzn2extra-docker                                            | 1.8 kB  00:00:00     
Resolving Dependencies
--> Running transaction check
---> Package dos2unix.x86_64 0:6.0.3-7.amzn2.0.2 will be installed
--> Finished Dependency Resolution 

Dependencies Resolved 

==================================================================================
  Package       Arch        Version            Repository            Size
==================================================================================
 Installing:
  dos2unix      x86_64      6.0.3-7.amzn2.0.2  amzn2-core            75 k
 
 Transaction Summary
==================================================================================
 Install  1 Package

 Total download size: 75 k
 Installed size: 194 k
 Is this ok [y/d/N]: y
 Downloading packages:
 dos2unix-6.0.3-7.amzn2.0.2.x86_64.rpm                      |  75 kB  00:00:00     
 Running transaction check
 Running transaction test
 Transaction test succeeded
 Running transaction
   Installing : dos2unix-6.0.3-7.amzn2.0.2.x86_64                          1/1 
   Verifying  : dos2unix-6.0.3-7.amzn2.0.2.x86_64                          1/1 

 Installed:
   dos2unix.x86_64 0:6.0.3-7.amzn2.0.2                                                                                                                         
 Complete! 

We are ready to convert our script using dos2unix!

[ec2-user@localhost scripts]$ dos2unix end_of_file.sh 
dos2unix: converting file end_of_file.sh to Unix format ... 

And now it’s time to execute it:

[ec2-user@localhost scripts]$ ./end_of_file.sh  No arguments passed

It works!

If you are interested I have written an article that explains the basics of Bash script arguments.

Conclusion

I have found myself having to use the dos2unix command several times over the years.

And now you know what to do if you see the syntax error “Unexpected end of file” while running a Bash script 🙂


Related FREE Course: Decipher Bash Scripting

Related posts:

I’m a Tech Lead, Software Engineer and Programming Coach. I want to help you in your journey to become a Super Developer!

EOJ needs to be fully left-justified, ie. no leading white-space, and no trailing space either. Also, you could/should (depending on your needs) write the first one as <<'EOJ' .. the quotes disable some shell expansion which can otherwise occur.

From info bash

Here Documents
This type of redirection instructs the shell to read input from the
current source until a line containing only delimiter (with no trailing
blanks) is seen. All of the lines read up to that point are then used
as the standard input for a command.

   The format of here-documents is:

          <<[-]word
                  here-document
          delimiter

   No  parameter expansion, command substitution, arithmetic expansion, or
   pathname expansion is performed on word.  If any characters in word are
   quoted,  the  delimiter is the result of quote removal on word, and the
   lines in the here-document are not expanded.  If word is unquoted,  all
   lines  of  the here-document are subjected to parameter expansion, com‐
   mand substitution, and arithmetic expansion.  In the latter  case,  the
   character  sequence  <newline> is ignored, and  must be used to quote
   the characters , $, and `.

   If the redirection operator is <<-, then all leading tab characters are
   stripped  from  input  lines  and  the line containing delimiter.  This
   allows here-documents within shell scripts to be indented in a  natural
   fashion.

EOJ needs to be fully left-justified, ie. no leading white-space, and no trailing space either. Also, you could/should (depending on your needs) write the first one as <<'EOJ' .. the quotes disable some shell expansion which can otherwise occur.

From info bash

Here Documents
This type of redirection instructs the shell to read input from the
current source until a line containing only delimiter (with no trailing
blanks) is seen. All of the lines read up to that point are then used
as the standard input for a command.

   The format of here-documents is:

          <<[-]word
                  here-document
          delimiter

   No  parameter expansion, command substitution, arithmetic expansion, or
   pathname expansion is performed on word.  If any characters in word are
   quoted,  the  delimiter is the result of quote removal on word, and the
   lines in the here-document are not expanded.  If word is unquoted,  all
   lines  of  the here-document are subjected to parameter expansion, com‐
   mand substitution, and arithmetic expansion.  In the latter  case,  the
   character  sequence  <newline> is ignored, and  must be used to quote
   the characters , $, and `.

   If the redirection operator is <<-, then all leading tab characters are
   stripped  from  input  lines  and  the line containing delimiter.  This
   allows here-documents within shell scripts to be indented in a  natural
   fashion.

я смог вырезать и вставить ваш код в файл, и он работал правильно. Если вы
выполните его так, как это должно работать:

ваш «file.sh»:

#!/bin/bash
# june 2011

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

команды:

$ ./file.sh arg1 arg2 arg3

обратите внимание, что «file.sh» должен быть исполняемым:

$ chmod +x file.sh

возможно, вы получаете эту ошибку b / c того, как вы делаете ввод (с трубой, морковью,
так далее.). Вы также можете попробовать разделить условие на два:

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

или, так как вы используете bash, вы может использовать встроенный синтаксис:

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

и, наконец, вы могли бы, конечно, просто проверить, если 3 аргумента были даны (чистый,
поддерживает совместимость оболочки POSIX):

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

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Синтаксическая ошибка на телевизоре андроид
  • Синоним к слову совершить ошибку