如何使用Linux命令行将文件作为电子邮件附件发送?

我创建了一个脚本,每天晚上在我的Linux服务器上运行,它使用mysqldump将我的每个MySQL数据库备份到.sql文件,并将它们打包成一个压缩的.tar文件。我想完成的下一步是通过电子邮件将tar文件发送到远程电子邮件服务器以确保安全。我已经能够通过将备份文本文件管道到mailx,像这样在电子邮件正文中发送原始脚本:

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

cat回显备份文件的文本,该文本通过管道传入mailx程序,并将收件人的电子邮件地址作为参数传递。

虽然这实现了我所需要的,我认为它可以更好的一步,是否有任何方法,使用shell脚本或其他方式,将压缩的.tar文件作为附件发送到外发电子邮件?这将击败必须处理非常长的电子邮件消息,其中包含标题数据和经常有换行问题等。

728481 次浏览

man mailx来看,mailx程序没有附加文件的选项。您可以使用其他程序,如mutt。

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

mutt的命令行选项可以用mutt -h显示。

你可以使用杂种狗来发送带有附件的电子邮件

mutt -s "Backup" -a mysqldbbackup.sql backup@example.com < message.txt

根据您的Linux版本,它可能被称为邮件。引用上文@David的话:

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

或者:

cat message.txt | mail -s "Backup" -a mysqldbbackup.sql backup@email.example

或者,失败的杂种:

gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz  | mail -s "MySQL DB" backup@email.com

Metamail有metasend工具

metasend -f mysqlbackup.sql.gz -t backup@email.com -s Backup -m application/x-gzip -b

我用的是packack。

mpack -s subject file user@example.com

不幸的是,mpack不能识别“-”作为stdin的别名。但下面的工作,并可以很容易地包装在一个(shell)别名或脚本:

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

我曾经在Solaris上为ksh写过这个函数(使用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
}

没有一个杂种对我有用。它以为电子邮件地址是附件的一部分。不得不这么做:

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

只是补充我的2分,我会写我自己的PHP脚本:

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

在该页上的示例中,有很多方法来处理附件。

发送带有mailx的明文正文电子邮件和一个明文附件:

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

下面是与上面相同的命令,没有换行符

( /usr/bin/uuencode /home/el/attachfile.txt myattachedfilename.txt; /usr/bin/echo "Body of text" ) | mailx -s 'Subject' youremail@example.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,读取这个:https://unix.stackexchange.com/questions/16277/how-do-i-get-uuencode-to-work

在Linux上,用sendmail发送HTML正文电子邮件和PDF附件:

确保你已经安装了ksh: yum info ksh

确保已经安装和配置了sendmail。

确保已安装uuencode并可用:https://unix.stackexchange.com/questions/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@example.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中的垃圾邮件过滤器可以将一个喷出电子邮件的域名列入黑名单,而不给你一个让他们通过的选项。你会发现它不再工作,或者它只允许通过附件,或者电子邮件根本无法通过。如果你必须在这方面做大量的测试,将它们分散在几天内,否则你将被标记为垃圾邮件发送者,这个功能将不再工作。

我使用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/

mailx现在确实有一个用于附件的-a选项。

不是一种发送电子邮件的方法,但你可以使用在线Git服务器(例如Bitbucket或类似的服务)。

这样,你可以使用git push命令,所有的版本将以压缩和有组织的方式存储。

我通常只在RHEL上使用mail命令。我试过mailx,它很有效率。

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


This is the content of my msg.


.

对我来说,最近的路是

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召回它来发送另一个文件…

 echo -e 'Hi, \n These are contents of my mail. \n Thanks' | mailx -s 'This is my email subject' -a /path/to/attachment_file.log -b bcc.email@example.com -c cc.email@example.com -r from.email@example.com to.email1@example.com to.email2@example.com to.email3@example.com

我使用

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

这对我来说很管用....

这是我在CentOS中处理一个大日志文件的方式:

#!/bin/sh
MAIL_CMD="$(which mail)"
WHOAMI="$(whoami)"
HOSTNAME="$(hostname)"
EMAIL"your@email.address"
LOGDIR="/var/log/aide"
LOGNAME="$(basename "$0")_$(date "+%Y%m%d_%H%M")"


if cd ${LOGDIR}; then
/bin/tar -zcvf "${LOGDIR}/${LOGNAME}".tgz "${LOGDIR}/${LOGNAME}.log" > /dev/null 2>&1
if [ -n "${MAIL_CMD}" ]; then
# This works too. The message content will be taken from text file below
# echo 'Hello!' >/root/scripts/audit_check.sh.txt
# echo "Attachment" | ${MAIL_CMD} -s "${HOSTNAME} Aide report" -q /root/scripts/audit_check.sh.txt -a ${LOGNAME}.tgz -S from=${WHOAMI}@${HOSTNAME} ${EMAIL}
echo "Attachment" | ${MAIL_CMD} -s "${HOSTNAME} Aide report" -a "${LOGNAME}.tgz" -S from="${WHOAMI}@${HOSTNAME}" "${EMAIL}"
/bin/rm "${LOGDIR}/${LOGNAME}.log"
fi
fi

从源机器

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

如果文件是文本,你可以在正文中最简单地发送它:

sendmail recipient@example.com < message.txt

如果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*

另一种选择- 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

使用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.example"
echo "Cc: user@company.example"
echo "From: Application"
echo "Subject: your subject"
echo  your body
uuencode $fileToAttach $fileToAttach
)| eval /usr/sbin/sendmail -t `;

这里有几个答案建议mailmailx,所以这更多的是一个背景,以帮助你在上下文中解释它们。但在最后还是有一些实用的建议。

历史记录

Unix mail的起源可以追溯到贝尔实验室Unix™(1969?)早期历史的迷雾中,我们可能不希望在这里了解它的全部谱系。只要说有许多程序从mail继承或重新实现(或从mail的重新实现继承代码),并且没有一个单一的代码基可以明确地标识为“the”就足够了。mail

然而,这个位置的竞争者之一当然是“伯克利邮报”。它最初在2BSD(1978)中被称为Mail,带有大写M;但是在3BSD(1979)中,它也替换了小写的mail命令,导致了一些新的混乱。SVR3(1986)包含了一个被称为mailx的导数。x的添加可能是为了使它唯一且不同;但是,这一点现在也被复制、重新实现和破坏,因此没有一个单独的版本是确定的。

在过去,通过电子邮件发送二进制文件的事实上的标准是uuencode。它仍然存在,但存在许多可用性问题;如果可能的话,你应该发送MIME附件,除非你特别努力能够与80年代后期通信。

MIME在20世纪90年代早期被引入,以解决电子邮件的几个问题,包括支持各种类型的内容,而不是单一字符集的纯文本,这只适合英语的一个子集(并且,我们被告知,夏威夷语)。这引入了对多部分消息、国际化、丰富内容类型等的支持,并在整个20世纪90年代迅速获得关注。

(传家宝__ABC0/mailx历史笔记在编写时最有帮助,如果你对这类事情感兴趣,当然值得一读。)

当前的产品

截至2018年,Debian有三个包,其中包括mailmailx命令。(你可以搜索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也是从这个发行版中获得这些软件包的。)

  • bsd-mailx是一个相对简单的mailx,它的似乎支持发送MIME附件。查看它的手册页并注意这是你期望在*BSD系统上(包括MacOS)默认情况下找到的。
  • heirloom-mailx现在被称为s-nail支持使用-a发送MIME附件。请参阅它的手册页和更普遍的传家宝项目
  • mailutils又名GNU Mailutils包含一个__ABC1/mailx兼容性包装器,其中支持用-A发送MIME附件

考虑到这些问题,如果你需要你的代码是可移植的,并且可以依赖于一个有点复杂的包,可移植地发送MIME附件的简单方法是使用mutt

如果你知道你在做什么,你可以在echobase64的帮助下组装一个任意的MIME结构,例如qprint(或自己生成的替换;base64qprint都可以很容易地实现为Perl的一行程序)并将其管道到sendmail;但本页上的其他几个答案生动地说明了,你可能不知道。

( printf '%s\n' \
"From: myself <sender@example.org>" \
"To: backup address <backup@email.example>" \
"Subject: Backup of $(date)" \
"MIME-Version: 1.0" \
"Content-type: application/octet-stream; filename=\"mysqldbbackup.sql\"" \
"Content-transfer-encoding: base64" \
""
base64 < mysqldbbackup.sql ) |
sendmail -oi -t

这假设sendmail在你的PATH上;有时不是(当然,有时根本没有安装)。查找/usr/lib/usr/sbin/usr/libexec等;或查询您的包管理器。一旦你找到它,你可能想要在脚本中增加你的PATH,或者硬编码完整的路径名sendmail(对于任何其他非标准二进制文件,它们可能安装在你的系统上,也可能没有安装)。

这仍然没有试图提供任何解决方案的情况下,你需要发送非ascii Unicode文本或行比SMTP允许的更长的,等等等等。对于一个健壮的解决方案,我会求助于现有的工具,如mutt,或现代脚本语言,如Python;https://docs.python.org/3/library/email.examples.html有许多常见用例的示例。

马鲁蒂尔斯把这事搞得小菜一碟

echo "Body" | mail.mailutils -M -s "My Subject" -A attachment.pdf mail@example.org
  • -A file附加一个文件
  • -M启用MIME,所以你可以有一个附件和明文正文。

如果尚未安装,请运行

sudo apt install mailutils