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

Kit*_*oed 282 linux email command-line

我创建了一个脚本,每天晚上在我的Linux服务器上运行,用于mysqldump将我的每个MySQL数据库备份到.sql文件,并将它们打包为一个压缩的.tar文件.我想要完成的下一步是通过电子邮件将该tar文件发送到远程电子邮件服务器以便妥善保管.我已经能够通过管道备份文本文件将正文脚本发送到正文中,mailx如下所示:

$ cat mysqldbbackup.sql | mailx backup@email.com
Run Code Online (Sandbox Code Playgroud)

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

虽然这实现了我的需要,但我认为它可能更好一步,有没有办法,使用shell脚本或其他方式将压缩的.tar文件作为附件发送到外发电子邮件? 这将不得不处理包含标题数据的非常长的电子邮件消息,并且通常会出现自动换行等问题.

ryn*_*nop 292

这些笨蛋都不适合我.它认为电子邮件地址是attachemnt的一部分.不得不做:

echo "This is the message body" | mutt -a "/path/to/file.to.attach" -s "subject of message" -- recipient@domain.com
Run Code Online (Sandbox Code Playgroud)

  • @fugitive意味着"选项结束".看看http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash (3认同)

Dan*_*one 79

或者,失败的笨蛋:

gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz  | mail -s "MySQL DB" backup@email.com
Run Code Online (Sandbox Code Playgroud)

  • 这将发送uuencoded部分**内联**而不是**附件**.许多邮件客户端都认识到了这一点,并且_display_ uuencoded部分作为附件. (24认同)
  • 他们都不使用邮件! (5认同)
  • 不要在这个时代使用uuencode.MIME稍微复杂一点,但更加用户友好. (4认同)

小智 41

通过查看man mailx,mailx程序没有附加文件的选项.你可以使用另一个程序,如mutt.

echo "This is the message body" | mutt -a file.to.attach -s "subject of message" recipient@domain.com
Run Code Online (Sandbox Code Playgroud)

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

  • 请参阅下面的答案(http://stackoverflow.com/a/9524359/10608),因为显然mutt的语法已更改,现在需要`--`. (9认同)

Nat*_*man 41

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

mail -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
Run Code Online (Sandbox Code Playgroud)

或者:

cat message.txt | mail -s "Backup" -a mysqldbbackup.sql backup@email.com 
Run Code Online (Sandbox Code Playgroud)

  • 而不是-a你应该使用-A:`-a, - append = HEADER:VALUE将给定标题附加到正在发送的消息``-A, - item = FILE attach FILE` (7认同)
  • 我的联机帮助页显示:``-a, - append = HEADER:VALUE将标题附加到正在发送的消息的标题`` (2认同)
  • 内森,看起来大卫的引用是错的 - 他使用了`mutt`命令,而不是`mail`.正如其他人所指出的那样,mutt现在似乎在地址之前需要一个` - `参数.我看到@exhuma和我实际上同意`mail`中的`-a`选项 - 我在那里迷茫了一分钟;) (2认同)

小智 28

我用mpack.

mpack -s subject file user@example.com
Run Code Online (Sandbox Code Playgroud)

不幸的是,mpack不会将' - '识别为stdin的别名.但是以下工作,可以很容易地包装在(shell)别名或脚本中:

mpack -s subject /dev/stdin loser@example.com < file
Run Code Online (Sandbox Code Playgroud)


Fre*_*ndt 27

我使用为此场景创建的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/

  • "sudo apt install sendemail" 安装 sendemail 并添加 "-f required@email.com" 一个必填字段,以便命令工作。` sendemail -f required@email.com-t to@some.one -m “这是你的文件!” -a file1.jpg file2.zip` (3认同)

Sou*_*nis 22

 echo 'These are contents of my mail' | mailx -s 'This is my email subject' -a /path/to/attachment_file.log email_id@example.com
Run Code Online (Sandbox Code Playgroud)

  • `mailx`没有正确标准化.任何建议的答案都应该指出这一点.通常使用至少三种不兼容的变体. (5认同)
  • 这应该是公认的答案.使用默认的mailx并完美运行.使用cron时,Mutt v1.5.21拒绝发送> 1MB的附件. (4认同)

Dav*_*gle 12

您可以使用mutt发送带附件的电子邮件

mutt -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
Run Code Online (Sandbox Code Playgroud)

  • 至少从mutt 1.5.21(Ubuntu trusty)开始,你需要在收件人后添加`-a`选项:`mutt -s"Backup"backup@email.com -a mysqldbbackup.sql <message.txt`,或者在收件人面前使用`--`选项,如rynop的回答所示. (2认同)

gle*_*man 12

我曾经在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
}
Run Code Online (Sandbox Code Playgroud)

  • 在GNU/Linux上,可以使用`base64`命令而不是perl进行编码 (7认同)

小智 9

使用mailx发送带有一个纯文本附件的明文正文电子邮件:

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

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

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

确保您拥有/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>
Run Code Online (Sandbox Code Playgroud)

如果您没有uuencode,请阅读:https://unix.stackexchange.com/questions/16277/how-do-i-get-uuencode-to-work

在Linux上,使用sendmail发送带有PDF附件的HTML正文电子邮件:

确保安装了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@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
Run Code Online (Sandbox Code Playgroud)

更改顶部的导出变量test.sh以反映您的地址和文件名.

下载测试pdf文档并将其放入/home/el名为pdf-test.pdf的文件中

创建一个名为/home/el/email_body.htm的文件并将此行放入其中:

<html><body><b>this is some bold text</b></body></html>
Run Code Online (Sandbox Code Playgroud)

确保pdf文件具有足够的755权限.

运行脚本 ./test.sh

检查您的电子邮件收件箱,文本应为HTML格式,pdf文件自动解释为二进制文件.小心不要在一天内使用此功能超过15次,即使您向自己发送电子邮件,gmail中的垃圾邮件过滤器也可以将滥用电子邮件的域名列入黑名单,而不会让您选择让它们通过.并且你会发现它不再有效,或者它只能通过附件,或者电子邮件根本没有通过.如果您必须对此进行大量测试,请将它们分散几天,否则您将被标记为垃圾邮件发送者,此功能将无法再使用.


tri*_*eee 8

这里有几个答案建议mail或者mailx更多的背景可以帮助您在上下文中解释这些.

历史笔记

Unix的起源mail可以追溯到贝尔实验室Unix™(1969年?)早期历史的迷雾中,我们可能不希望在这里进入完整的家谱.可以这么说,有许多程序继承代码或重新实现(或从重新实现继承代码),mail并且没有单一的代码库可以明确地标识为"the" mail.

然而,这个位置的竞争者之一当然是"伯克利邮报",最初Mail在2BSD(1978)中以大写字母M 命名; 但是在3BSD(1979)中,它也取代了小写mail命令,导致了一些新的混乱.SVR3(1986)包括被称为的衍生物mailx.在x大概是添加,使其独特而鲜明的; 但是,这也已被复制,重新实现和删除,因此没有单一的个人版本是明确的.

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

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

(传家宝mail/ 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
Run Code Online (Sandbox Code Playgroud)

(我不是把Debian单独作为推荐;它是我使用的,所以我熟悉它;它提供了一种通过引用它们各自的包名来明确区分各种备选方法的方法.显然也是来自哪个Ubuntu获得这些包.)

  • bsd-mailx是一个相对简单mailx,似乎支持发送MIME附件.请参阅其手册页并注意,默认情况下,这是您期望在*BSD系统(包括MacOS)上找到的那个.
  • heirloom-mailx现在被调用s-nail,支持发送MIME附件-a.请参阅其手册页以及更一般的Heirloom项目
  • mailutils又名GNU Mailutils包含一个mail/ mailx兼容包装器,支持发送MIME附件-A

考虑到这些问题,如果您需要可移植代码并且可能依赖于某种复杂的程序包,则可以使用可移植地发送MIME附件的简单方法.mutt


Ale*_*ruk 5

另一种选择 - 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
Run Code Online (Sandbox Code Playgroud)