Запускаем следующий скрипт:
#!/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_
завершается ошибкой с Connection closed by host
сообщением сразу после ответа сервера с помощью escape-символа и до доставки 220
сообщения.
Запуск соответствующей последовательности в интерактивном режиме (конечно, без «here-doc») достигает моей цели.
Я подозреваю, что «передача» командных строк серверу происходит не совсем так, как ожидается на другом конце линии.
Верны ли мои предположения? Есть ли способ смягчить эту проблему?
решение1
Когда вам нужно создать сценарий для интерактивного инструмента командной строки, типичным решением является использование expect(1)
.
решение2
Для полноты картины я публикую здесь полное «некрасивое, но работающее» решение (с поправкой на то, что в окончательном виде оно отправляет электронные письма большему количеству людей, а также предоставляет вложение):
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
Можно выбрать игру с задержками. И, как (я думаю) более надежное решение, я бы выбрал expect(1)
.