3

I'm trying to write a bash script but I'm still getting this error:

here document `cmd' unclosed

I don't know what is wrong; please can you help?

#!/bin/bash
USER='login'
PASS='password'

echo $USER
echo $PASS

cd /tmp
for plik in *.tar.gz
do
    echo $plik  
    ftp -niv 192.168.12.2 << cmd
    user $USER $PASS
    cd /centrala/nagrania
    put $plik
    bye 
    cmd
done

I'm looping over all *.tar.gz for send multiple files to ftp server and this error is stopping me.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
przeqpiciel
  • 328
  • 2
  • 12

2 Answers2

3

This should work:

ftp -niv 192.168.12.2 <<-cmd
    user $USER $PASS
    cd /centrala/nagrania
    put $plik
    bye 
cmd

As per manual:

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.

That means you need to use <<- form to have natural indentation of your code using tab characters.

mklement0
  • 382,024
  • 64
  • 607
  • 775
anubhava
  • 761,203
  • 64
  • 569
  • 643
2
  • By default, a here-doc closing delimiter must start at the very beginning of the line, otherwise it won't be recognized.

  • Alternatively, if you prefix the opening delimiter with -, then the closing delimiter may have leading tabs - but only true \t characters, not spaces. Note that this also strips leading tabs from the lines of the document itself.

It is unfortunate that bash offers no option to trim leading spaces (too), given that many editors have the option to insert multiple spaces instead of true tab (\t) chararacters when the user presses the TAB key.

Since the difference between multiple spaces and genuine tabs:

  • is usually not obvious (you typically can't tell by looking at it, as in the question),
  • copying and pasting may even quietly convert from tabs to spaces

the more robust solution is NOT to rely on using the - prefix - sadly, at the expense of readability (depending on how the string is used, leading spaces in the document itself - as opposed to the closing delimiter - may still be acceptable, though):

# ...      
for plik in *.tar.gz
do
    echo $plik  

    cat << cmd
user $USER $PASS
cd /centrala/nagrania
put $plik
bye 
cmd

done
mklement0
  • 382,024
  • 64
  • 607
  • 775