Отправка письма из shell

Автор: | 5 декабря 2011

Как отправить письмо с вложением из оболочки UNIX? Есть несколько вариантов, я рассмотрю самые простые, – системными средствами и сторонним ПО.

mail + uuencode

Почти наверняка самый рабочий способ на любой системе.

~> ( echo "body text message" ; echo ; cat file.txt | uuencode file.txt ) | mail -s 'Subject' to@domain.tld

в почтовый ящик придет сообщение в виде:

To: to@domain.tld
Subject: Subject
Message-Id: <20111205165235.0DB932ECAC@dom.tld>
Date: Mon,  5 Dec 2011 16:52:35 +0000 (UTC)
From: sender@domain.tld (sender)

body text message

begin 644 file.txt
M+W-B:6XO;61M9G,@+7,@-#`Y-DT@+6D@,3`R-"`M=R!M>7-Q;#IM>7-Q;"`M
M<"`W-S<@;60P("]M>7-Q;%]T;7`*(R,M+2TM+2TC(PT*26YC;W)R96-T(&EN
...
M;F1E>"YP:'`[(&-D("T[(&QS("UL82`D:2]I;F1E>"YP:'`[(&1O;F4*(R,M
)+2TM+2TC(PH*
`
end

Плюсы: универсальный способ, не требует установки дополнительного ПО

Минусы: не все почтовые клиенты понимают этот формат и письмо возможно придется раскодировывать. Если вы пользуетесь почтой Гугла (GMail) – вам повезло, такой формат он понимает и файл можно будет скачать как обычный прикрепленный файл.

mail + base64
~> cat file.txt | base64 | mail -s 'Subject' to@dom.tld
~> cat file.txt | uuencode -m file.txt | mail -s 'Subj' to@dom.tld

Плюсы: файл в письме отправится

Минусы: письмо наверняка будет не понято почтовым клиентом и вложение будет просто выведено в виде текста, который нужно дополнительно распаковывать. GMail такие письма не понимает.

sendmail
~> ( cat header ; cat ssh.txt | base64 ) | /usr/sbin/sendmail -t
~> ( cat header ; cat ssh.txt | uuencode -m ssh.txt ) | /usr/sbin/sendmail -t
~>
~> ( cat header ; cat ssh.txt | uuencode ssh.txt ) | /usr/sbin/sendmail -t
# это не правильно, но GMail понимает и такой формат

В файл header предварительно внесены необходимые заголовки:

~> cat header
Subject: With attachment
From: me@dom.tld
To: to@domain.tld
Content-Type: text/plain; charset=UTF-8
Content-Disposition: attachment; filename="file.txt"
Content-Transfer-Encoding: base64

Здесь мы явно указываем кодировку файла (UTF-8), имя файла, которое будет показываться в письме (может не совпадать с именем файла, который мы кодируем) и метод кодирования (base64). В третьем примере файл будет закодирован в uuencode, это тоже может вызвать сложности у почтовых клиентов. uuencode –m, в отличие от base64, помечает начало и конец закодированных данных, так же, как и просто uuencode. В первом случае начало данных будет помечено строкой:

begin-base64 644 file.txt

конец:

====

во втором случае:

begin 644 file.txt

конец:

end

Плюсы: письмо понимается большинством почтовых клиентов

Красиво и по всем правилам отправить письмо можно с помощью скрипта:

#!/bin/sh
FROM=me@dom.tld
TO=to@domain.tld
SUBJECT="Letter with attachement"
MIME="text/plain"  # Adjust this to the proper mime-type of file
attachment=file.txt
ENCODING=base64
boundary="---text-for-mime-boundary---$$--"
DATE=`date +"%a, %e %Y %T %z"`

( cat <<EOF
From: $FROM
To: $TO
Subject: $SUBJECT
Date: $DATE
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="$boundary"
Content-Disposition: inline

--$boundary
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Body message: This email has attached the file

--$boundary
Content-Type: $MIME;name="$attachment"
Content-Disposition: attachment;filename="$attachment"
Content-Transfer-Encoding: $ENCODING

EOF

base64 $attachment
echo ""
echo "--$boundary--" ) | sendmail -t

Можно допилить этот скрипт, чтобы он принимал вложение (имя файла).

Как определить кодировку файла?
~> file -i -b u-file.txt
text/plain charset=utf-8
~> file -i -b file.txt
text/plain charset=unknown

В моем случае cp1251 и koi8-r не определяются(

mutt
~> echo "Body message" | mutt -a file.txt -s "Subject" -- to@dom.tld
~> echo "Body message" | mutt to@dom.tld -s "Subject" -a ssh.txt

Если указан ключ -a, необходимо указывать — перед указанием адресата, т.к. с этим ключом можно указывать несколько файлов для прикрепления к письму.

Плюсы: удобно отправлять один или несколько файлов во вложении.

Минусы: кириллические файлы в формате UTF-8 могут не открываться в GMail или почтовом клиенте, т.к. тип text/plain mutt кодирует по умолчанию как quoted-printable, а не base64. Для насильного кодирования текстовых файлов в base64 можно создать файл:

~> echo "application/octet-stream txt" >> ~/.mime.types
mailx

Точнее, heirloom-mailx:

~> echo "Body message" | /usr/local/bin/mailx -a 1.txt -s "Subject" to@dom.tld
~> echo "Body message" | /usr/local/bin/mailx -a 1.txt -a 2.txt -s "Subject" to@dom.tld

Так можно отправить один или два файла во вложении. В отличие от mutt, для каждого файла нужно добавлять ключ -a.

mailx помечает текстовый файл как application/octet-stream, а не text/plain.

mutt и mailx можно установить из портов, /usr/ports/mail/heirloom-mailx и /usr/ports/mail/mutt соответственно.

Плюсы: удобно отправлять один или несколько файлов во вложении.

Отправка письма из shell: 2 комментария

Добавить комментарий