Как отправить файл в виде вложения электронной почты с помощью командной строки Linux?

290

Я создал сценарий, который запускается каждую ночь на моем сервере Linux, который использует mysqldumpдля резервного копирования каждой из моих баз данных MySQL файлы .sql и упаковывает их вместе в сжатый файл .tar. Следующим шагом, который я хочу выполнить, является отправка этого tar-файла по электронной почте на удаленный почтовый сервер для безопасного хранения. Я смог отправить сырой сценарий в теле письма по электронной почте, скопировав файл резервной копии mailxпримерно так:

$ cat mysqldbbackup.sql | mailx backup@email.com

catповторяет текст файла резервной копии, который передается в mailxпрограмму с адресом электронной почты получателя, переданным в качестве аргумента.

В то время как это выполняет то, что мне нужно, я думаю, что это может быть на один шаг лучше, есть ли способ, используя сценарии оболочки или иным образом, отправить сжатый файл .tar в исходящее сообщение электронной почты в виде вложения ? Это избавило бы от необходимости иметь дело с очень длинными сообщениями электронной почты, которые содержат данные заголовка и часто имеют проблемы с переносом слов и т. Д.

Кит Роед
источник
1
Можете ли вы поделиться сценарием, который резервирует ваши базы данных MySQL?
Almino Melo
Извините, я давно этим не занимался. Я знаю, что это связано с вызовом, mysqldumpа затем присоединение вывода к электронной почте (с mutt). Возможно, у меня даже был шаг, который сжимал вывод в zip / tar.gz ...
Kit Roed
1
Просто любопытно, зачем по электронной почте ваши резервные копии против scp или rsync их?
июня

Ответы:

298

Никто из дураков не работал на меня. Он думал, что адрес электронной почты был частью Attachemnt. Должен сделать:

echo "This is the message body" | mutt -a "/path/to/file.to.attach" -s "subject of message" -- recipient@domain.com
rynop
источник
1
Я использую Mutt 1.5.21 (2010-09-15), и для него требуется параметр -a после электронной почты получателя
nurettin
Я работал с использованием Mutt 1.5.24 (2015-08-30) на openSUSE Leap 42.1.
Антонио Виниций Менезес Медей
3
@fugitive означает «конец опций». Взгляните на unix.stackexchange.com/questions/11376/…
rynop
Есть ли способ проверить наличие исключений и повторить отправку?
ti034
79

Или провалившийся дурак:

gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz  | mail -s "MySQL DB" backup@email.com
Даниэль Фон
источник
26
Это отправляет кодированную часть в линию, а не как вложение . Хотя многие почтовые клиенты распознают это и отображают часть с uuencoded как вложение.
FuePi
4
Не используйте uuencode в этот день и возраст. MIME немного сложнее, но намного удобнее для пользователя.
tripleee
@DavidGiven: Посмотрите, например, (быстрым взглядом) все остальные ответы на этот вопрос.
трипл
6
Никто из них не использует почту!
Дэвид дал
Затем, например, stackoverflow.com/questions/3317174/… и замените его text/htmlна любой тип MIME, подходящий для вашего вложения. (Для этого конкретного примера, я думаю application/gzip.)
tripleee
44

В зависимости от вашей версии linux это может называться mail. Процитировать @David выше:

mail -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt

или также:

cat message.txt | mail -s "Backup" -a mysqldbbackup.sql backup@email.com 
Натан Феллман
источник
@ KarelBílek: Как насчет другого варианта?
Натан Феллман
Оба решения не работают для меня. Я получил письмо с outlook 2013, и письмо содержит только имя файла
nickel715
2
Моя -a, --append=HEADER: VALUE append given header to the message being sent
справочная
2
Натан, похоже, твоя цитата из Дэвида неверна - он использовал muttкоманду, а не mail. Также, как отмечали другие, теперь Mutt, похоже, требует --аргумент перед адресом. И я вижу, что @exhuma и я на самом деле согласны с тем, что делает -aопция mail- я запутался там на минуту;)
nealmcb
7
вместо -a вы должны использовать -A: -a, --append=HEADER: VALUE append given header to the message being sent -A, --attach=FILE attach FILE
Виктор Перов
41

Глядя на man mailx, программа mailx не имеет опции для прикрепления файла. Вы можете использовать другую программу, такую ​​как Mutt.

echo "This is the message body" | mutt -a file.to.attach -s "subject of message" recipient@domain.com

Параметры командной строки для Mutt могут быть показаны с mutt -h.

Крис Н
источник
Спасибо! Это сработало, у меня возникли проблемы с тем, чтобы сделать что-то молча.
Кит Рёд
10
Смотрите ответ ниже ( stackoverflow.com/a/9524359/10608 ), потому что, очевидно, синтаксис изменился для Mutt, который теперь требует --.
Александр Берд
29

Я использую SendEmail, который был создан для этого сценария. Он упакован для Ubuntu, поэтому я предполагаю, что он доступен

sendemail -f sender@some.where -t receiver@some.place -m "Here are your files!" -a file1.jpg file2.zip

http://caspian.dotconf.net/menu/Software/SendEmail/

Фредрик Вендт
источник
Я полагаю, это должен быть "sendEmail" вместо "sendemail" в вашем примере.
Давид
1
Да и нет - источник (caspian) использует заглавную букву E, в то время как это необычная стратегия именования инструментов командной строки (в мире Unix), по крайней мере, пакет Ubuntu для этого программного обеспечения обеспечивает как sendemailи так и sendEmailвнутри /usr/bin/.
Фредрик Вендт
Мой Xubuntu 14.04.3 не установленSendEmail
Виталий Зданевич
3
«sudo apt install sendemail» для установки sendemail и добавления «-f required@email.com» обязательного поля from для команды для работы. sendemail -f mandatory@email.com-t to@some.one -m "Here are your files!" -a file1.jpg file2.zip
Сайлендра Пинуполу
28

Я использую mpack.

mpack -s subject file user@example.com

К сожалению, mpack не распознает '-' как псевдоним для stdin. Но следующая работа и может быть легко заключена в псевдоним (shell) или скрипт:

mpack -s subject /dev/stdin loser@example.com < file

источник
Это может работать в Bash для STDIN. У меня нет mpack, поэтому я не пробовал:mpack -s subject /dev/stdin loser@example.com <(stdout_generating_program)
thomasa88
23
 echo 'These are contents of my mail' | mailx -s 'This is my email subject' -a /path/to/attachment_file.log email_id@example.com
Сурабх Потнис
источник
4
Это должен быть принятый ответ. Использует по умолчанию mailx и работает отлично. Mutt v1.5.21 отказывается отправлять вложения размером более 1 МБ при использовании cron.
Джозеф
Я искал что-то, что работает в EC2, и это работало нормально.
особенность
6
mailxне должным образом стандартизирован. Любой ответ, который рекомендует это, должен указать это предостережение. Существует как минимум три несовместимых варианта общего пользования.
tripleee
13

Однажды я написал эту функцию для ksh в Solaris (использует Perl для кодирования base64):

# usage: email_attachment to cc subject body attachment_filename
email_attachment() {
    to="$1"
    cc="$2"
    subject="$3"
    body="$4"
    filename="${5:-''}"
    boundary="_====_blah_====_$(date +%Y%m%d%H%M%S)_====_"
    {
        print -- "To: $to"
        print -- "Cc: $cc"
        print -- "Subject: $subject"
        print -- "Content-Type: multipart/mixed; boundary=\"$boundary\""
        print -- "Mime-Version: 1.0"
        print -- ""
        print -- "This is a multi-part message in MIME format."
        print -- ""
        print -- "--$boundary"
        print -- "Content-Type: text/plain; charset=ISO-8859-1"
        print -- ""
        print -- "$body"
        print -- ""
        if [[ -n "$filename" && -f "$filename" && -r "$filename" ]]; then
            print -- "--$boundary"
            print -- "Content-Transfer-Encoding: base64"
            print -- "Content-Type: application/octet-stream; name=$filename"
            print -- "Content-Disposition: attachment; filename=$filename"
            print -- ""
            print -- "$(perl -MMIME::Base64 -e 'open F, shift; @lines=<F>; close F; print MIME::Base64::encode(join(q{}, @lines))' $filename)"
            print -- ""
        fi
        print -- "--${boundary}--"
    } | /usr/lib/sendmail -oi -t
}
Гленн Джекман
источник
8
В GNU / Linux base64для кодирования можно использовать команду вместо perl
MestreLion
12

Вы можете использовать Mutt, чтобы отправить письмо с приложением

mutt -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
Дэвид Шлоснагл
источник
2
По крайней мере, начиная с Mutt 1.5.21 (Ubuntu trusty), вам нужно поставить -aопцию после получателя: mutt -s "Backup" backup@email.com -a mysqldbbackup.sql < message.txtили использовать --опцию перед получателем, как показано в ответе rynop.
nealmcb
10

Отправьте текстовое электронное письмо с одним вложенным текстом в формате mailx:

(
  /usr/bin/uuencode attachfile.txt myattachedfilename.txt; 
  /usr/bin/echo "Body of text"
) | mailx -s 'Subject' youremail@gmail.com

Ниже та же команда, что и выше, без перевода строки

( /usr/bin/uuencode /home/el/attachfile.txt myattachedfilename.txt; /usr/bin/echo "Body of text" ) | mailx -s 'Subject' youremail@gmail.com

Убедитесь, что у вас есть файл, /home/el/attachfile.txtопределенный с этим содержанием:

<html><body>
Government discriminates against programmers with cruel/unusual 35 year prison
sentences for making the world's information free, while bankers that pilfer 
trillions in citizens assets through systematic inflation get the nod and 
walk free among us.
</body></html>

Если у вас нет uuencode, прочитайте это: /unix/16277/how-do-i-get-uuencode-to-work

В Linux отправьте основную электронную почту в формате HTML с вложением PDF с помощью sendmail:

Убедитесь, что у вас установлен ksh: yum info ksh

Убедитесь, что у вас установлен и настроен sendmail.

Убедитесь, что у вас установлен и доступен код uuencode: /unix/16277/how-do-i-get-uuencode-to-work

Создайте новый файл с именем test.shи поместите его в свой домашний каталог:/home/el

Введите следующий код в test.sh:

#!/usr/bin/ksh
export MAILFROM="el@defiant.com"
export MAILTO="youremail@gmail.com"
export SUBJECT="Test PDF for Email"
export BODY="/home/el/email_body.htm"
export ATTACH="/home/el/pdf-test.pdf"
export MAILPART=`uuidgen` ## Generates Unique ID
export MAILPART_BODY=`uuidgen` ## Generates Unique ID

(
 echo "From: $MAILFROM"
 echo "To: $MAILTO"
 echo "Subject: $SUBJECT"
 echo "MIME-Version: 1.0"
 echo "Content-Type: multipart/mixed; boundary=\"$MAILPART\""
 echo ""
 echo "--$MAILPART"
 echo "Content-Type: multipart/alternative; boundary=\"$MAILPART_BODY\""
 echo ""
 echo "--$MAILPART_BODY"
 echo "Content-Type: text/plain; charset=ISO-8859-1"
 echo "You need to enable HTML option for email"
 echo "--$MAILPART_BODY"
 echo "Content-Type: text/html; charset=ISO-8859-1"
 echo "Content-Disposition: inline"
 cat $BODY
 echo "--$MAILPART_BODY--"

 echo "--$MAILPART"
 echo 'Content-Type: application/pdf; name="'$(basename $ATTACH)'"'
 echo "Content-Transfer-Encoding: uuencode"
 echo 'Content-Disposition: attachment; filename="'$(basename $ATTACH)'"'
 echo ""
 uuencode $ATTACH $(basename $ATTACH)
 echo "--$MAILPART--"
) | /usr/sbin/sendmail $MAILTO

Измените переменные экспорта в верхней части, test.shчтобы они отражали ваш адрес и имена файлов.

Загрузите тестовый pdf документ и поместите его в /home/elфайл pdf-test.pdf.

Создайте файл с именем /home/el/email_body.htm и вставьте в него следующую строку:

<html><body><b>this is some bold text</b></body></html>

Убедитесь, что файл PDF имеет достаточные права доступа 755.

Запустить скрипт ./test.sh

Проверьте свою электронную почту, текст должен быть в формате HTML, а файл PDF автоматически интерпретируется как двоичный файл. Старайтесь не использовать эту функцию более, чем, скажем, 15 раз в день, даже если вы отправляете электронные письма себе, спам-фильтры в gmail могут занести в черный список домен, извергающий электронные письма, не давая вам возможности пропустить их. И вы обнаружите, что это больше не работает, или только пропускает вложение, либо электронное письмо вообще не приходит. Если вам нужно много тестировать по этому поводу, распределите их по дням, или вы будете помечены как спамер, и эта функция больше не будет работать.

user1651561
источник
1
Для меня это сработало наоборот. (echo 'Email Body'; uuencode filename filename) | mailx -s 'Subject' user@domain.com
Вики
uuencodeэто не правильно вложение. Он просто встраивает читаемый компьютером блок текста в середину другого текста. Раньше он работал нормально, когда не было лучшего механизма, но это было более 20 лет назад.
tripleee
9

Есть несколько ответов здесь предлагая mailили mailxтак это скорее фон , чтобы помочь вам интерпретировать их в контексте.

Исторические заметки

Происхождение Unix mailвосходит к туманам ранней истории Bell Labs Unix ™ (1969?), И мы, вероятно, не можем надеяться углубиться в его полную генеалогию здесь. Достаточно сказать, что есть много программ, которые наследуют код или переопределяют (или наследуют код от переопределения) mailи что не существует единой базы кода, которая может быть однозначно идентифицирована как «the» mail.

Тем не менее, одним из претендентов на эту должность, безусловно, является «Почта Беркли», которая первоначально была названа Mailзаглавной буквой М в 2BSD (1978); но в 3BSD (1979) он также заменил команду в нижнем регистре mail, что привело к некоторой новой путанице. SVR3 (1986) включал производную, которая была названа mailx. xПредположительно добавил , чтобы сделать его уникальным и различны; но теперь это тоже было скопировано, переопределено и искалечено, так что нет единой отдельной версии, которая была бы окончательной.

В свое время стандартом де-факто для отправки двоичных файлов по электронной почте был uuencode. Он все еще существует, но имеет множество проблем с юзабилити; если это вообще возможно, вы должны вместо этого отправлять вложения MIME, если только вы специально не пытаетесь общаться с концом 1980-х годов.

MIME был представлен в начале 1990-х годов для решения ряда проблем с электронной почтой, включая поддержку различных типов контента, кроме простого текста, в одном наборе символов, который действительно подходит только для подмножества английского языка (и, как нам говорят, на гавайском языке) ). Это привело к поддержке многокомпонентных сообщений, интернационализации, богатых типов контента и т. Д. И быстро завоевало популярность в течение 1990-х годов.

( Семейные заметки mail/ mailxисторические заметки были наиболее полезны при составлении этого, и, безусловно, их стоит прочитать, если вы любите подобные вещи.)

Текущие предложения

Начиная с 2018 года в Debian есть три пакета, в которые входит команда mailили mailx. (Вы можете искать Provides: mailx.)

debian$ aptitude search ~Pmailx
i   bsd-mailx                       - simple mail user agent
p   heirloom-mailx                  - feature-rich BSD mail(1)
p   mailutils                       - GNU mailutils utilities for handling mail

(Я не выделяю Debian в качестве рекомендации; это то, чем я пользуюсь, поэтому я с ним знаком; и он дает возможность однозначно различать различные альтернативы, ссылаясь на их соответствующие имена пакетов. Это, очевидно, также дистрибутив какая Ubuntu получает эти пакеты.)

С этими проблемами, если вам нужен код , чтобы быть портативным и может зависеть от степени сложного пакета, простой способ переносимым отправлять вложения MIME является использование mutt.

tripleee
источник
Первоначально я разместил это как ответ на довольно популярный дубликат вопроса stackoverflow.com/questions/902591/…
tripleee
4

Другая альтернатива - Swaks (Швейцарский армейский нож для SMTP).

swaks -tls \
    --to ${MAIL_TO} \
    --from ${MAIL_FROM} \
    --server ${MAIL_SERVER} \
    --auth LOGIN \
    --auth-user ${MAIL_USER} \
    --auth-password ${MAIL_PASSWORD} \
    --header "Subject: $MAIL_SUBJECT" \
    --header "Content-Type: text/html; charset=UTF-8" \
    --body "$MESSAGE" \
    --attach mysqldbbackup.sql
Александр Янчарук
источник
2

у метапочты есть инструмент мета отправка

metasend -f mysqlbackup.sql.gz -t backup@email.com -s Backup -m application/x-gzip -b
Gunstick
источник
Раньше его устанавливали почти везде, но почти никогда не использовали. Поскольку он долгое время не обслуживался (и до сих пор остается AFAIK), он был удален из стандартного набора инструментов де-факто на многих платформах.
tripleee
2

я использовал

echo "Start of Body" && uuencode log.cfg readme.txt | mail -s "subject" "a@b.c" 

и это хорошо сработало для меня ....

пончо
источник
1

Я обычно использую только команду mail на RHEL. Я пробовал mailx, и это довольно эффективно.

mailx -s "Sending Files" -a First_LocalConfig.conf -a
Second_LocalConfig.conf Recipient@myemail.com

This is the content of my msg.

.
Алехандро Сантиллан
источник
1

кратчайший путь для меня

file=filename_or_filepath;uuencode $file $file|mail -s "optional subject" email_address

так что для вашего примера это будет

file=your_sql.log;gzip -c $file;uuencode ${file}.gz ${file}|mail -s "file with magnets" ph.gachoud@gmail.com

хорошая часть в том, что я могу вспомнить его с помощью Ctrl + r, чтобы отправить другой файл ...

Pipo
источник
Скобки не принесут вам большой пользы, но чтобы быть полностью переносимым, вы должны использовать двойные кавычки вокруг переменных. См. Также stackoverflow.com/questions/10067266/…
tripleee
1

С исходной машины

mysqldump --defaults-extra-file=sql.cnf database | gzip | base64 | mail me@myemail.com

На пункте назначения машины. Сохранить полученное почтовое тело как db.sql.gz.b64 ; затем..

base64 -D -i db.sql.gz.b64 | gzip -d | mysql --defaults-extra-file=sql.cnf
Кёнчог
источник
0

Чтобы добавить свои 2 цента, я бы написал свой собственный PHP Script:

http://php.net/manual/en/function.mail.php

Есть много способов сделать вложение в примерах на этой странице.

Майк Граф
источник
2
Не на каждом сервере может быть установлен PHP. Если вы действительно хотите пойти по пути «напишите свой собственный скрипт», тогда Perl или Python лучше подходят, так как они обычно доступны по умолчанию.
exhuma
shеще более вездесущ. Есть дублирующие вопросы с ответами с хорошими примерами; вот мой
tripleee
0

mailxдействительно есть -aопция для вложений.

Аллан Пинто
источник
2
Опция "-a" предназначена для заголовков
Ив Мартин,
man mail [x], версия 12.5 от 9.10.10 (несколько лет назад) ясно говорит: -a файл Прикрепите данный файл к сообщению.
fche
4
некоторые версии mailxделают. Я считаю, что есть две реализации. С одной стороны -a, для вложений, с другой - для заголовков.
exhuma
1
Версия mailx в Ubuntu взята из GNU и там -a означает добавить заголовок. manpages.ubuntu.com/manpages/lucid/en/man1/mailx.1.html Какая система и какой mailx вложения?
nealmcb
3
В новой реализации «-a» для заголовков и «-A» для прикреплений
Ави Мехенвал
0

Не способ отправки электронной почты, но вы можете использовать для этого онлайн-сервер Git (например, Bitbucket или подобный сервис).

Таким образом, вы можете использовать git pushкоманды, и все версии будут храниться в сжатом и упорядоченном виде.

Yoav
источник
0

Вот как я делаю с одним большим файлом журнала в CentOS:

MAIL="`whereis mail | awk '{print $2}'`"
WHOAMI="`whoami`"
HOSTNAME="`hostname`"
EMAIL"your@email.address"
LOGDIR="/var/log/aide"
LOGNAME="`basename "$0"`_`date "+%Y%m%d_%H%M"`"
# Arhiveerime ning kui hästi, saadame edasi:
/bin/tar -zcvf ${LOGDIR}/${LOGNAME}.tgz "${LOGDIR}/${LOGNAME}.log" > /dev/null 2>&1
if [ $? -eq 0 ]; then
    cd ${LOGDIR}
    # This works too. The message content will be taken from text file below
    # echo 'Hello!' >/root/scripts/audit_check.sh.txt
    # echo "Arhiivifail manuses" | ${MAIL} -s "${HOSTNAME} Aide report" -q /root/scripts/audit_check.sh.txt -a ${LOGNAME}.tgz -S from=${WHOAMI}@${HOSTNAME} ${EMAIL}
    echo "Arhiivifail manuses" | ${MAIL} -s "${HOSTNAME} Aide report" -a ${LOGNAME}.tgz -S from=${WHOAMI}@${HOSTNAME} ${EMAIL}
    /bin/rm "${LOGDIR}/${LOGNAME}.log"
fi
dagorv
источник
Почему ты определяешь WHOAMIи HOSTNAME дважды?
Дэвид С. Ранкин
Это имеет несколько ошибок стиля кодирования оболочки. Shellcheck.net укажет некоторые, но не все, из них.
tripleee
0

Если файл текстовый, вы можете отправить его проще всего в теле как:

sendmail recipient@example.com < message.txt
nurp
источник
1
Это не отправляет его как вложение или даже как тело сообщения. Sendmail ожидает, что его ввод будет полным, правильно сформированным почтовым сообщением RFC5322, и может не получиться интересным образом, если это не так.
tripleee
0

используя команду mailx

 echo "Message Body Here" | mailx -s "Subject Here" -a file_name user@example.com

используя sendmail

#!/bin/ksh

fileToAttach=data.txt

`(echo "To: user@company.com"
  echo "Cc: user@company.com"
  echo "From: Application"
  echo "Subject: your subject"
  echo  your body
  uuencode $fileToAttach $fileToAttach
  )| eval /usr/sbin/sendmail -t `;
Girdhar Singh Rathore
источник
1
sendmail - хороший пример, рад, что нашел его здесь.
Хонза П.
Обратите внимание, что вам нужна пустая строка в начале «вашего тела», иначе тело исчезнет в заголовках или, возможно, полностью прервет сообщение. Также смотрите заметки в другом месте о том, как избегать uuencodeMIME.
tripleee
И чудовищные, evalи загадочные задиры вокруг всего устройства здесь совершенно не нужны.
tripleee
0

Mailutils делает это кусок пирога

echo "Body" | mail.mailutils -M -s "My Subject" -A attachment.pdf mail@example.org
  • -A file прикрепляет файл
  • -M включает MIME, так что вы можете иметь вложение и текстовое тело.

Если еще не установлен, запустите

sudo apt install mailutils
Румпель
источник
0

В зависимости от параметров вашей почтовой команды (проверьте это с помощью man mail) и версии вы можете сделать

echo yourBody|mail -s yoursubject -A /your/attachment/file john@doe.com

Pipo
источник
Похоже, что это дублирует существующие ответы, не добавляя ничего нового, особенно этот -Aпараметр относится к mailutilsверсии GNU, о которой mailговорилось в моем ответе, а также к @ rumpel's
tripleee
-1

Если Mutt не работает или не установлен, попробуйте это

*#!/bin/sh

FilePath=$1
FileName=$2
Message=$3
MailList=$4

cd $FilePath

Rec_count=$(wc -l < $FileName)
if [ $Rec_count -gt 0 ]
then
(echo "The attachment contains $Message" ; uuencode $FileName $FileName.csv ) | mailx -s "$Message" $MailList
fi*
Парас Сингх
источник