1

Running the following script:

#!/bin/bash cvs_domain=abc.com cvs_mail_server=mail.${cvs_domain} cvs_port=25 telnet $cvs_mail_server $cvs_port<<_EOF_ EHLO $cvs_domain MAIL FROM:[email protected] RCPT TO:[email protected] DATA Subject:Test! Don't panic. This is only a test. . QUIT _EOF_ 

fails with a Connection closed by host message, right after the server replying with the escape character, and before serving the 220 message.

Running the corresponding sequence in interactive mode (of course, without the "here-doc") accomplishes my goal.

I suspect "feeding" the command lines to the server doesn't happen exactly as expected at the other end of the line.

Is my assumption correct? Is there a way to mitigate this problem?

3
  • 1
    I suggest you watch what is going on in wireshark Commented May 18, 2016 at 23:40
  • you write "without the "here-doc" " <-- what? those words don;t occur anywhere Commented May 18, 2016 at 23:41
  • @barlop This should've crossed my mind! Excellent idea (Wireshark). As for the "here-doc", I was referring to tldp.org/LDP/abs/html/here-docs.html . Commented May 18, 2016 at 23:41

2 Answers 2

1

When you need to script an interactive command-line tool, the typical solution is to use expect(1).

2
  • Even though this is the elegant answer, I was able to find a way around this issue by applying the second technique (braced expressions) mentioned by thiton in his answer here: stackoverflow.com/questions/7013137/… . A pure Bash solution may be preferable under certain scenarios. Commented May 19, 2016 at 13:42
  • Just to make sure I'm thorough, I also introduced delays (sleep 1) between my commands. "Here-doc" notation no longer necessary. Commented May 19, 2016 at 13:49
0

For sake of the completeness, I am posting here the full "ugly-but-it-works" solution (with the amends that, in its final form, it sends emails to more people, as well as provides an attachment):

cd "$(dirname "$0")" working_dir=$(pwd) # switching to the folder this script has been started from cvs_domain=mail.org cvs_mail_server=mail.${cvs_domain} cvs_port=25 [email protected] cvs_recipients=([email protected] [email protected]) cvs_delimiter=-----nEXt_paRt_frontier!!VSFCDVGGERHERZZ@$%^zzz--- # MIME multi-part delimiter, do not change { echo HELO $cvs_domain; sleep 1 # set up the email (sender, receivers): echo MAIL FROM:$cvs_sender; sleep 1 for r in ${cvs_recipients[@]}; do echo RCPT TO:$r; sleep 1 done echo DATA; sleep 1 echo From:$cvs_sender; sleep 1 for r in ${cvs_recipients[@]}; do echo To:$r; sleep 1 done echo Subject:Test for build; sleep 1 # build the mail structure, according to the MIME standard: echo MIME-Version: 1.0; sleep 1 echo "Content-Type: multipart/mixed; boundary=\"$cvs_delimiter\""; sleep 1 echo --${cvs_delimiter}; sleep 1 echo Content-Type: text/plain; sleep 1 echo; sleep 1 echo Don\'t panic. This is only a test.; sleep 1 echo; sleep 1 echo --${cvs_delimiter}; sleep 1 echo "Content-Type: text/plain; name=\"test.txt\""; sleep 1 echo "Content-Disposition: attachment; filename=\"test.txt\""; sleep 1 echo "Content-Transfer-Encoding: base64"; sleep 1 echo; sleep 1 encoded_file=$( base64 ./change.log ) # encoding the contents of the file, according to the declaration above echo "$encoded_file"; sleep 1 echo; sleep 1 echo --${cvs_delimiter}; sleep 1 echo .; sleep 1 echo QUIT sleep 1; } | telnet $cvs_mail_server $cvs_port 

One may choose to fiddle with the delays. And, for (what I think may be) a more robust solution, I would go with expect(1).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.