如何使用 Linux 命令行将文件作为电子邮件附件发送?
-
08-06-2019 - |
题
我创建了一个每天晚上在我的 Linux 服务器上运行的脚本,它使用 mysqldump
将我的每个 MySQL 数据库备份到 .sql 文件并将它们打包在一起作为压缩的 .tar 文件。我想要完成的下一步是通过电子邮件将该 tar 文件发送到远程电子邮件服务器以进行妥善保管。我已经能够通过将备份文本文件通过管道发送到正文中的原始脚本 mailx
像这样:
$ cat mysqldbbackup.sql | mailx backup@email.com
cat
回显备份文件的文本,该文本通过管道传输到 mailx
程序将收件人的电子邮件地址作为参数传递。
虽然这满足了我的需要,但我认为它可能会更好, 有没有办法使用 shell 脚本或其他方式将压缩的 .tar 文件作为外发电子邮件发送到 依恋? 这将不必处理包含标题数据并且经常存在自动换行问题等的很长的电子邮件。
解决方案
没有一个对我有用。它认为电子邮件地址是附件的一部分。不得不做:
echo "This is the message body" | mutt -a "/path/to/file.to.attach" -s "subject of message" -- recipient@domain.com
其他提示
或者,失败的杂种:
gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz | mail -s "MySQL DB" backup@email.com
从看 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
.
根据您的 Linux 版本,它可能被称为邮件。引用上面@David的话:
mail -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
或者也:
cat message.txt | mail -s "Backup" -a mysqldbbackup.sql backup@email.com
我用的是mpack。
mpack -s subject file user@example.com
不幸的是,mpack 无法将“-”识别为标准输入的别名。但以下工作可以轻松地包装在(shell)别名或脚本中:
mpack -s subject /dev/stdin loser@example.com < file
我使用 SendEmail,它是为此场景创建的。它是为 Ubuntu 打包的,所以我认为它是可用的
sendemail -f sender@some.where -t receiver@some.place -m "Here are your files!" -a file1.jpg file2.zip
echo 'These are contents of my mail' | mailx -s 'This is my email subject' -a /path/to/attachment_file.log email_id@example.com
您可以使用 杂种狗 发送带有附件的电子邮件
mutt -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
我曾经在 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@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,请阅读以下内容: 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
更改顶部的导出变量 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 中的垃圾邮件过滤器也会将发送电子邮件的域列入黑名单,而不给您允许它们通过的选项。您会发现这不再起作用,或者它只允许通过附件,或者电子邮件根本无法通过。如果您必须对此进行大量测试,请将它们分散在几天内,否则您将被标记为垃圾邮件发送者,并且此功能将不再起作用。
这里有几个答案建议 mail
或者 mailx
所以这更多的是帮助你在上下文中解释这些内容的背景。
历史笔记
Unix 的起源 mail
回到贝尔实验室 Unix™(1969 年?)的早期历史的迷雾中,我们可能无法希望在这里了解其完整的谱系。可以这么说,有许多程序继承或重新实现代码(或从重新实现继承代码) mail
并且不存在可以明确标识为“the”的单一代码库 mail
.
然而,这一职位的竞争者之一无疑是《伯克利邮报》,它最初被称为 Mail
2BSD (1978) 中带有大写的 M;但在 3BSD (1979) 中,它取代了小写 mail
命令也是如此,导致一些新的混乱。SVR3 (1986) 包括一个衍生品,称为 mailx
. 。这 x
大概是为了使其独特和独特而添加的;但现在它也被复制、重新实现和修改,因此没有一个单独的版本是确定的。
回到当年, 事实上的 通过电子邮件发送二进制文件的标准是 uuencode
. 。它仍然存在,但存在许多可用性问题;如果可能的话,您应该发送 MIME 附件,除非您特别努力能够与 20 世纪 80 年代后期进行交流。
哑剧 于 20 世纪 90 年代初推出,旨在解决电子邮件的几个问题,包括支持除单一字符集中的纯文本之外的各种类型的内容,该字符集仅真正适合英语的子集(而且,我们被告知,夏威夷语) 。这引入了对多部分消息、国际化、丰富内容类型等的支持,并在整个 90 年代迅速获得关注。
(这 传家宝 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 从中获取这些软件包的发行版。)
bsd-mailx
是一个比较简单的mailx
这确实 不是 似乎支持发送 MIME 附件。见其 手册页 请注意,这是您期望在 *BSD 系统(包括 MacOS)上默认找到的。heirloom-mailx
现在被称为s-nail
和 做 支持发送 MIME 附件-a
. 。见其 手册页 更一般地说 传家宝项目mailutils
又名 GNU Mailutils 包括一个mail
/mailx
兼容性包装器 哪个 做 支持发送 MIME 附件-A
考虑到这些问题,如果您需要代码可移植并且可以依赖于有些复杂的包,则可移植地发送 MIME 附件的简单方法是 使用 mutt
.
另一种选择—— 斯瓦克斯 (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
元邮件有工具metasend
metasend -f mysqlbackup.sql.gz -t backup@email.com -s Backup -m application/x-gzip -b
我用了
echo "Start of Body" && uuencode log.cfg readme.txt | mail -s "subject" "a@b.c"
这对我来说效果很好......
mailx
确实有一个 -a
现在可以选择附件。
我通常只在 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 发送另一个文件...
从源机器
mysqldump --defaults-extra-file=sql.cnf database | gzip | base64 | mail me@myemail.com
在目标机器上。将收到的邮件正文保存为 数据库.sql.gz.b64;然后..
base64 -D -i db.sql.gz.b64 | gzip -d | mysql --defaults-extra-file=sql.cnf
使用mailx命令
echo "Message Body Here" | mailx -s "Subject Here" -a file_name user@example.com
使用发送邮件
#!/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 `;
不是发送电子邮件的方法,但您可以使用在线 Git 服务器(例如Bitbucket 或类似的服务)。
这样,您可以使用 git push
命令,所有版本都将以压缩和组织的方式存储。
这就是我在 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
如果文件是文本,您可以在正文中最简单地发送它,如下所示:
sendmail recipient@example.com < message.txt
Mailutils 让这变得轻而易举
echo "Body" | mail.mailutils -M -s "My Subject" -A attachment.pdf mail@example.org
-A file
附上一个文件-M
启用 MIME,以便您可以拥有附件和纯文本正文。
如果尚未安装,请运行
sudo apt install mailutils
还有一件事是关于 mutt
: :默认情况下,它在“发件人:”字段中使用您的地址和姓名。如果这不是您所需要的,您可以创建包含如下字符串的替代 muttrc 文件:设置自=“我的邮件守护程序”
使用此文件 -F
命令行选项。
如果 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*