使用 crontab 作业发送邮件,邮件文本变成一个名为 ATT00001.bin 的附件
Posted
技术标签:
【中文标题】使用 crontab 作业发送邮件,邮件文本变成一个名为 ATT00001.bin 的附件【英文标题】:Use crontab job send mail, The email text turns to an attached file which named ATT00001.bin 【发布时间】:2013-09-30 17:40:27 【问题描述】:我想在一台 linux 服务器上分析一些数据,然后将其作为电子邮件文本发送到我的电子邮件帐户,但是当我在 shell 命令中执行这个 shell 脚本时,效果很好,奇怪的是当我把所有的程序进入 crontab 作业,Email 文本会变成附件,有人可以帮忙吗?
#* * * * * sh -x /opt/bin/exec.sh >> /opt/bin/mailerror 2>&1
/* exec.sh */
#/bin/sh
cd /opt/bin
./analysis.sh > test
mail -s "Today's Weather" example@example.com < test
但是当我直接在 shell 命令行中执行 exec.sh 时,Email 会收到文本,谁能帮我解释一下,感激不尽。
【问题讨论】:
【参考方案1】:我自己也遇到了同样的问题,只是我将文本输出传送到 mailx
- Heirloom mailx 12.4 7/29/08
在命令行上运行脚本时,电子邮件作为带有文本正文的普通电子邮件出现。
然而,当我通过crontab
运行完全相同的脚本时,电子邮件的正文以附件形式出现 - ATT00001.BIN (Outlook)、application/octet-stream (mutt) 或“noname” (Gmail)。
进行了一些研究来解决这个问题,但这里是:
问题
如果在文本输入中遇到未知/控制字符,Mailx 会将其转换为设置了 application/octet-stream mime-type 的附件。
来自手册页:
对于包含除换行符和水平制表符以外的格式字符的任何文件
所以你需要删除那些控制字符,这可以通过tr
来完成
echo "$Output" | /usr/bin/tr -cd '\11\12\15\40-\176' | mail ...
但是,由于我有挪威 UTF8 字符:æøå - 列表扩展,您并不想维护这样的列表,我需要挪威字符。
检查附件我发现我只有 \r,\n 范围为 32-176 的“常规”ASCII 字符 - 所有可打印 和 184 和 195 --> UTF8
解决方案
在脚本中明确设置语言环境:
LANG="en_US.UTF8" ; export LANG
在您的 shell 中运行 export
- 如果您运行 csh
或 tcsh
,则运行 setenv
以确定您的语言环境设置。
说明
Mailx - 在您的 shell 中运行时 - LANG 设置为 .UTF8,将正确识别 UTF8 字符并继续。
在crontab
中运行时,未设置 LANG,默认为 LANG=C,因为默认情况下 crontab 将仅运行一组受限的环境变量(取决于系统)。
mailx(或其他程序)然后将不识别 UTF8 字符并确定输入包含未知控制字符。
我的问题是 UTF8 字符,您的问题可能是输入中的其他控制字符。通过hexdump
或od -c
运行它,但由于它在常规shell 中工作正常,我怀疑LANG 问题。
参考资料:
linux mail < file.log has Content-Type: application/octet-stream (a noname attachment in Gmail) http://alvinalexander.com/blog/post/linux-unix/how-remove-non-printable-ascii-characters-file-unix【讨论】:
您的回答对我帮助很大。 (我已经导出了 LANG="ko_KR.utf8") 感谢您的回答。在我的脚本中设置语言为我解决了这个问题。【参考方案2】:我遇到了同样的问题,以上都没有解决问题。移动文件中的额外回报为我解决了这个问题:
cat logfile | tr -d \\r | mailx -s'the logfile' to-me@.....
感谢这个论坛:
https://forums.opensuse.org/showthread.php/445955-mailx-creates-unwanted-attachment
【讨论】:
【参考方案3】:确保在脚本中更改此设置
#/bin/sh
替换为
#!/bin/sh
解决问题
您的脚本假定它是从特定目录运行的(请注意,几乎每个路径都是相对路径,而不是绝对路径)。 cron 恰好是从另一个目录运行它。
修复电子邮件中出现的文本
mydir=$(dirname "$0") && cd "$mydir" || exit 1
./opt/bin/analysis.sh > test
mail -s "Today's Weather" example@example.com < /opt/bin/test
说明
$0 是正在执行的 shell 脚本的(可能是相对的)文件名。给定一个文件名,dirname 命令返回包含该文件名的目录。 因此,如果 dirname 或 cd 失败,则该行会将目录更改为包含脚本的目录或以错误代码退出。
或尝试使用完整路径,例如
./opt/bin/analysis.sh > test
mail -s "Today's Weather" example@example.com < /opt/bin/test
注意:前面讨论过同样的问题here
跟进:
尝试删除
sh -x /opt/bin/exec.sh >> /opt/bin/mailerror 2>&1
改为使用
sh /opt/bin/exec.sh 2>&1 >> /opt/bin/mailerror
跟进
如果您不使用 crontab 命令编辑文件,则必须重新启动 cron 才能使更改生效。
crontab -l > oldcrontab
cp oldcrontab newcrontab
echo "$newline" >> newcrontab
crontab < newcrontab
【讨论】:
嘿,伙计,我尝试了各种方法,但都失败了,我不知道该怎么办。 请发布 uname 输出以及完整的脚本输出 你能给我一个电子邮件,我会把整个文件发给你。 你有没有尝试后续的答案??修改大陆请发到这里 如果您需要帮助,请发布 uname 输出以及完整的脚本输出。【参考方案4】:在我的例子中,cron 不是一个 shell 脚本,而是一个 PHP 脚本(所以我不能放 export LANG
这个东西):
0 9 * * * apache php /test/myscript.php | mail -s "CRON - myscript" foo@bar.com
解决方案:
为了解决同样的问题(内容作为附件而不是正文邮寄),我在 cron 文件的开头添加了 LANG=fr_FR.UTF-8
:
MAILTO=vme1.etc-crond-backoffice-conf
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
LANG=fr_FR.UTF-8
0 9 * * * apache php /test/myscript.php | mail -s "CRON - myscript" foo@bar.com
注意:将LANG=fr_FR.UTF-8
放入/etc/environment
文件并重新启动cron 服务也可以。
参考:
在 crontab 中设置 LANG https://www.logikdev.com/2010/02/02/locale-settings-for-your-cron-job/【讨论】:
以上是关于使用 crontab 作业发送邮件,邮件文本变成一个名为 ATT00001.bin 的附件的主要内容,如果未能解决你的问题,请参考以下文章