BASH: here-document at line n delimited by end-of-file (wanted `EOF’)

On one of our Debian hosts, we use bash scripts and cron jobs to automate certain tasks. One of these bash scripts downloads files from an FTP server and archives them. After upgrading the host machine to Debian 6.0.4, one of the bash scripts suddenly showed warnings:

/srv/foo/bar.sh: line 146: warning: here-document at line 140 delimited by end-of-file (wanted `EOF')

Whoops, so let’s look into it. The change was probably introduced with the new version of bash:

$ bash --version
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)

So let’s look into the script itself. The following lines are used to get a directory listing from an FTP server using the ftp command and these are also the lines that throw the warning. The script reads as follows:

FTP_DIR_LISTING=`ftp -n $FTP_SERVER << EOF
        user $FTP_USERNAME $FTP_PASSWORD
        cd $FTP_DIRECTORY
        dir
        bye
        EOF`

It turns out (also see here and here), that the \t in front of the “EOF” is a bit problematic, as is any character after “EOF”.

So to solve the problem, simply remove any characters before and after the “EOF”. This means to remove all tabs, whitespaces, special characters etc. before and after the EOF, excluding the bash syntax:

FTP_DIR_LISTING=`ftp -n $FTP_SERVER << EOF
        user $FTP_USERNAME $FTP_PASSWORD
        cd $FTP_DIRECTORY
        dir
        bye
EOF`

Now the scripts runs fine and the output of the ftp command is saved in the variable FTP_DIR_LISTING. This output can now be processed with awk. Here is an example:

echo $FTP_DIR_LISTING | awk '{for(i=9;i<=90;i+=9) printf "%s\n",$i};' | while read SINGLE_FILENAME; do
	echo $SINGLE_FILENAME
done

Hello world

My name is Simon Krenger, I am a Technical Account Manager (TAM) at Red Hat. I advise our customers in using Kubernetes, Containers, Linux and Open Source.

Elsewhere

  1. GitHub
  2. LinkedIn
  3. GitLab