提问人:Kit Roed 提问时间:8/20/2008 最后编辑:Stephen OstermillerKit Roed 更新时间:12/7/2022 访问量:751966
如何使用 Linux 命令行将文件作为电子邮件附件发送?
How do I send a file as an email attachment using Linux command line?
问:
我创建了一个脚本,每天晚上在我的 Linux 服务器上运行,用于将我的每个 MySQL 数据库备份到 .sql 文件,并将它们打包为压缩的 .tar 文件。我要完成的下一步是通过电子邮件将该 tar 文件发送到远程电子邮件服务器进行保管。我已经能够通过管道将备份文本文件发送到正文中的原始脚本一封电子邮件,如下所示:mysqldump
mailx
$ cat mysqldbbackup.sql | mailx [email protected]
cat
回显备份文件的文本,该文本通过管道传递到程序中,收件人的电子邮件地址作为参数传递。mailx
虽然这完成了我需要的,但我认为它可以更好一步,有没有办法使用 shell 脚本或其他方式将压缩的 .tar 文件作为附件发送到传出电子邮件?这将胜过必须处理包含标题数据并且经常有自动换行问题等的非常长的电子邮件。
答:
从 来看,mailx 程序没有附加文件的选项。您可以使用其他程序,例如 mutt。man mailx
echo "This is the message body" | mutt -a file.to.attach -s "subject of message" [email protected]
mutt 的命令行选项可以用 来显示。mutt -h
评论
--
man mailx
您可以使用 mutt 发送带有附件的电子邮件
mutt -s "Backup" -a mysqldbbackup.sql [email protected] < message.txt
评论
-a
mutt -s "Backup" [email protected] -a mysqldbbackup.sql < message.txt
--
根据您的 Linux 版本,它可能被称为邮件。引用上面@David:
mail -s "Backup" -a mysqldbbackup.sql [email protected] < message.txt
或者:
cat message.txt | mail -s "Backup" -a mysqldbbackup.sql [email protected]
评论
mail
-a, --append=HEADER: VALUE append given header to the message being sent
mutt
mail
--
-a
mail
-a, --append=HEADER: VALUE append given header to the message being sent
-A, --attach=FILE attach FILE
或者,失败的 mutt:
gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz | mail -s "MySQL DB" [email protected]
评论
text/html
application/gzip
Metamail 有工具 Metasend
metasend -f mysqlbackup.sql.gz -t [email protected] -s Backup -m application/x-gzip -b
评论
我使用mpack。
mpack -s subject file [email protected]
不幸的是,mpack 无法将 '-' 识别为 stdin 的别名。但是以下工作,可以很容易地包装在(shell)别名或脚本中:
mpack -s subject /dev/stdin [email protected] < file
评论
mpack -s subject /dev/stdin [email protected] <(stdout_generating_program)
我曾经在 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
}
评论
base64
没有一个对我有用。它认为电子邮件地址是附件的一部分。必须做:
echo "This is the message body" | mutt -a "/path/to/file.to.attach" -s "subject of message" -- [email protected]
评论
mutt
只是为了增加我的 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' [email protected]
下面是与上面相同的命令,没有换行符
( /usr/bin/uuencode /home/el/attachfile.txt myattachedfilename.txt; /usr/bin/echo "Body of text" ) | mailx -s 'Subject' [email protected]
请确保您有一个使用以下内容定义的文件:/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 发送带有 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="[email protected]"
export MAILTO="[email protected]"
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文档,并将其放入名为pdf-test的.pdf/home/el
创建一个名为 /home/el/email_body.htm 的文件,并将以下行放入其中:
<html><body><b>this is some bold text</b></body></html>
确保 pdf 文件具有足够的 755 权限。
运行脚本./test.sh
检查您的电子邮件收件箱,文本应为 HTML 格式,pdf 文件应自动解释为二进制文件。注意不要在一天内使用此功能超过 15 次,即使您将电子邮件发送给自己,gmail 中的垃圾邮件过滤器也可以将喷出电子邮件的域列入黑名单,而不会让您选择让它们通过。你会发现这不再有效,或者它只允许通过附件,或者电子邮件根本没有通过。如果您必须对此进行大量测试,请将它们分散在几天内,否则您将被标记为垃圾邮件发送者,并且此功能将不再起作用。
评论
(echo 'Email Body'; uuencode filename filename) | mailx -s 'Subject' [email protected]
uuencode
不是正确的附件。它只是在其他一些文本的中间嵌入一个可读的文本块。当没有更好的机制时,它曾经工作得很好,但那是 20+ 年前的事了。
ksh
sh
ksh
我使用为此方案创建的 SendEmail。它是为 Ubuntu 打包的,所以我认为它是可用的
sendemail -f [email protected] -t rece[email protected] -m "Here are your files!" -a file1.jpg file2.zip
http://caspian.dotconf.net/menu/Software/SendEmail/
评论
sendemail
sendEmail
/usr/bin/
SendEmail
sendemail -f [email protected] [email protected] -m "Here are your files!" -a file1.jpg file2.zip
mailx
现在确实有附件选项。-a
评论
mailx
-a
不是一种发送电子邮件的方法,但您可以使用在线 Git 服务器(例如 Bitbucket 或类似服务)。
这样,您可以使用命令,所有版本都将以压缩和有组织的方式存储。git push
我通常只在 RHEL 上使用 mail 命令。我尝试过mailx,它非常有效。
mailx -s "Sending Files" -a First_LocalConfig.conf -a
Second_LocalConfig.conf [email protected]
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" [email protected]
好的部分是我可以用 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 [email protected] -c [email protected] -r [email protected] to[email protected] [email protected] [email protected]
评论
mailx
没有适当的标准化。任何建议它的答案都应该指出这一点。通常至少有三种不相容的变体。
echo -e
我用过
echo "Start of Body" && uuencode log.cfg readme.txt | mail -s "subject" "[email protected]"
这对我来说效果很好......
评论
echo
mail
uuencode
这是我在 CentOS 中处理一个大型日志文件的方式:
#!/bin/sh
MAIL_CMD="$(which mail)"
WHOAMI="$(whoami)"
HOSTNAME="$(hostname)"
EMAIL"[email protected]"
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
评论
WHOAMI
HOSTNAME
which
PATH
mail
${MAIL_CMD}
which
command -v
type
从源计算机
mysqldump --defaults-extra-file=sql.cnf database | gzip | base64 | mail [email protected]
在目标计算机上。将收到的邮件正文另存为 db.sql.gz.b64;然后。。
base64 -D -i db.sql.gz.b64 | gzip -d | mysql --defaults-extra-file=sql.cnf
评论
如果文件是文本,则可以在正文中将其发送为:
sendmail [email protected] < 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*
评论
uuencode
另一种选择 - 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
评论
smtp.gmail.com
使用 mailx 命令
echo "Message Body Here" | mailx -s "Subject Here" -a file_name [email protected]
使用 Sendmail
#!/bin/ksh
fileToAttach=data.txt
`(echo "To: [email protected]"
echo "Cc: [email protected]"
echo "From: Application"
echo "Subject: your subject"
echo your body
uuencode $fileToAttach $fileToAttach
)| eval /usr/sbin/sendmail -t `;
评论
uuencode
eval
这里有几个答案,或者说这更像是一个背景,以帮助你在上下文中解释这些。但是在接近尾声时有一些实用的建议。mail
mailx
历史笔记
Unix邮件
的起源可以追溯到贝尔实验室Unix™(1969?)的早期历史的迷雾中,我们可能不能指望在这里了解它的完整谱系。我只想说,有许多程序继承了代码或重新实现(或从重新实现中继承了代码),并且没有一个单一的代码库可以被明确地标识为“the”。mail
mail
然而,该职位的竞争者之一当然是“伯克利邮报”,它最初在 2BSD (1978) 中以大写字母 M 命名;但在 3BSD(1979 年)中,它也取代了小写命令,导致了一些新的混乱。SVR3 (1986) 包括一种称为 .据推测,添加它是为了使其独特而与众不同;但现在,这也被复制、重新实现和肢解,因此没有一个单独的版本是确定的。Mail
mail
mailx
x
过去,通过电子邮件发送二进制文件的实际标准是 uuencode
。它仍然存在,但存在许多可用性问题;如果可能的话,您应该改为发送 MIME 附件,除非您特别努力能够与 1980 年代后期进行通信。
MIME 于 1990 年代初引入,旨在解决电子邮件的几个问题,包括支持除单个字符集中的纯文本以外的各种类型的内容,这些内容实际上只适合英语的一个子集(我们被告知,夏威夷语)。这引入了对多部分消息、国际化、丰富内容类型等的支持,并在整个 1990 年代迅速获得关注。
(Heirloom mail
/mailx
历史笔记在撰写本文时最有帮助,如果您喜欢这种东西,当然值得一读。
当前产品/服务
截至 2018 年,Debian 有三个软件包,其中包含 or 命令。(您可以搜索 .)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 获取这些软件包的发行版。
bsd-mailx
是一个相对简单的,似乎不支持发送 MIME 附件。请参阅其手册页,并注意这是您希望在 *BSD 系统(包括 MacOS)上默认找到的手册。mailx
heirloom-mailx
现在正在被调用,并且支持发送带有 的 MIME 附件。请参阅其手册页,以及更一般的 Heirloom 项目s-nail
-a
mailutils
又名 GNU Mailutils 包含一个mail
/mailx
兼容性包装器,它确实支持使用-A
有了这些顾虑,如果你需要你的代码是可移植的,并且可以依赖于一个有点复杂的包,那么可移植地发送MIME附件的简单方法是使用。mutt
如果你知道自己在做什么,你可以借助 和 和 来组装一个任意的 MIME 结构,例如 qprint
(或自产的替代品;两者都可以很容易地实现为 Perl 单行)并将其输送到;但正如本页上的其他几个答案生动地说明的那样,你可能不知道。echo
base64
base64
qprint
sendmail
( printf '%s\n' \
"From: myself <[email protected]>" \
"To: backup address <[email protected]>" \
"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 允许的长度等情况提供任何解决方案。对于一个强大的解决方案,我会求助于现有的工具,如 ,或现代脚本语言,如 Python;https://docs.python.org/3/library/email.examples.html 提供了许多常见用例的示例。mutt
评论
Mailutils 使这成为小菜一碟
echo "Body" | mail.mailutils -M -s "My Subject" -A attachment.pdf [email protected]
-A file
附加文件-M
启用 MIME,以便您可以拥有附件和纯文本正文。
如果尚未安装,请运行
sudo apt install mailutils
评论
mysqldump
mutt