Как отправить файл в виде вложения электронной почты с помощью командной строки 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

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 могут занести в черный список домен, извергающий электронные письма, не давая вам возможности пропустить их. И вы обнаружите, что это больше не работает, или только пропускает вложение, либо электронное письмо вообще не приходит. Если вам нужно много тестировать по этому поводу, распределите их по дням, или вы будете помечены как спамер, и эта функция больше не будет работать.


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.


Первоначально я разместил это как ответ на довольно популярный дубликат вопроса 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

Раньше его устанавливали почти везде, но почти никогда не использовали. Поскольку он долгое время не обслуживался (и до сих пор остается 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, чтобы отправить другой файл ...


Скобки не принесут вам большой пользы, но чтобы быть полностью переносимым, вы должны использовать двойные кавычки вокруг переменных. См. Также 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команды, и все версии будут храниться в сжатом и упорядоченном виде.


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

Почему ты определяешь WHOAMIи HOSTNAME дважды?
Дэвид С. Ранкин

Это имеет несколько ошибок стиля кодирования оболочки. Shellcheck.net укажет некоторые, но не все, из них.
tripleee

0

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

sendmail recipient@example.com < message.txt

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 `;

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


Похоже, что это дублирует существующие ответы, не добавляя ничего нового, особенно этот -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*
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.