1

I'm creating a Bash script file on iOS X that asks the user if they would like to upload a file to a server. The sftp command (with a delimiter) works fine outside the if statement but when I put the sftp command (with the delimiter) inside the if statement, I get this error message: "upload.sh: line nnn: syntax error: unexpected end of file"

printf "Upload file? [y]es?"
read -r input1
if [ $input1 == "y" ] || [ $input1 == "yes" ]; then
  sftp -i key.txt user@server << DELIMITER
    put local/path/to/file /server/upload/dir
    quit
  DELIMITER
fi

What am I missing here?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Jawa
  • 99
  • 2
  • 12

2 Answers2

3

The heredoc marker shouldn't be indented (I assume you are using spaces for indentation). Rewrite your code this way:

printf "Upload file? [y]es?"
read -r input1
if [ "$input1" == "y" ] || [ "$input1" == "yes" ]; then
  sftp -i key.txt user@server << DELIMITER
    put local/path/to/file /server/upload/dir
    quit
DELIMITER
fi

It's important to enclose your variable in double quotes to prevent issues arising from word splitting, globbing, and an empty string breaking your test ([ ... ]) command.


See also:

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • 1
    Thanks @codeforester! I was unaware of the indentation issue with heredoc markers. – Jawa May 22 '17 at 20:17
2

If you want to use TAB indents with heredoc then the redirection operator << should be followed by a - (dash), resulting in <<-. Any leading TAB in the heredoc will then be ignored.

printf "Upload file? [y]es?"
read -r input1
if [ "$input1" = "y" ] || [ "$input1" = "yes" ]; then
    sftp -i key.txt user@server <<- DELIMITER
        put local/path/to/file /server/upload/dir
        quit
    DELIMITER
fi

An alternative would be simple input redirection which could be used instead of heredoc:

printf "Upload file? [y]es?"
read -r input1
if [ "$input1" = "y" ] || [ "$input1" = "yes" ]; then
  sftp -i key.txt user@server < \
  <(echo "put local/path/to/file /server/upload/dir ; quit")
fi 

Also there's no reason to use ==; use = instead when comparing strings within single brackets. If using double brackets the meaning changes, so it's usually better habit to use it consistently.

l'L'l
  • 44,951
  • 10
  • 95
  • 146