Как отправить письмо с вложением из оболочки 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 соответственно.
Плюсы: удобно отправлять один или несколько файлов во вложении.
Как насчет быстроты выполнения?
выполнятся быстро 😉