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

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

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

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


当前回答

 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

其他回答

我曾经在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
}

发送带有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

Check your email inbox, the text should be in HTML format and the pdf file automatically interpreted as a binary file. Take care not to use this function more than say 15 times in a day, even if you send the emails to yourself, spam filters in gmail can blacklist a domain spewing emails without giving you an option to let them through. And you'll find this no longer works, or it only lets through the attachment, or the email doesn't come through at all. If you have to do a lot of testing on this, spread them out over days or you'll be labelled a spammer and this function won't work any more.

这里有几个关于mail或mailx的答案,所以这更多的是一个背景知识,帮助你在上下文中理解它们。但在最后还是有一些实用的建议。

历史记录

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

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

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

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

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

当前的产品

截至2018年,Debian有三个包,其中包括一个mail或mailx命令。(你可以搜索providers: 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是一个相对简单的邮件,它似乎不支持发送MIME附件。请参阅它的手册页,并注意这是您期望在*BSD系统上(包括MacOS)默认情况下找到的。 传家宝-mailx现在被称为s-nail,并且支持用-a发送MIME附件。查看它的手册页和更一般的传家宝项目 mailutils(又名GNU mailutils)包含一个邮件/邮件兼容包装器,它支持使用-A发送MIME附件

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

如果你知道你在做什么,你可以在echo和base64的帮助下组装一个任意的MIME结构,例如qprint(或本地替换;base64和qprint都可以很容易地实现为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或etc;或查询您的包管理器。找到它之后,您可能希望在脚本中增加PATH,或者将完整的路径名硬编码到sendmail(对于系统上可能安装也可能没有安装的任何其他非标准二进制文件也是如此)。

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

我使用SendEmail,它就是为这个场景创建的。它是为Ubuntu打包的,所以我认为它是可用的

sendemail -f sender@some.where -t receiver@some.place -m“这是你的文件!”-a file1.jpg file2.zip

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

我用的是packack。

mpack -s subject file user@example.com

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

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