我想分析一台Linux服务器中的一些数据,然后将其作为电子邮件文本发送到我的电子邮件帐户,但是当我在shell命令中执行这个shell脚本时,它运行良好,奇怪的是当我将所有过程放入crontab中时工作,电子邮件文本将变成附件,有人可以帮忙吗?
#* * * * * 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" [email protected] < test
但是当我直接在 shell 命令行中执行 exec.sh 时,电子邮件会收到文本,有人可以帮我解释一下吗,谢谢。
我自己也遇到了同样的问题,只是我将文本输出通过管道传输到
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 字符:æøå - 列表扩展,并且您实际上不想维护这样的列表,而我需要挪威语字符。
检查附件时我发现我只有 , 32-176 范围内的“常规”ASCII 字符 - 所有可打印和 184 和 195 --> UTF8
解决方案
在脚本中显式设置区域设置:
LANG="en_US.UTF8" ; export LANG
在 shell 中运行
export
- 或者如果运行 setenv
或 csh
来确定您的区域设置,则运行 tcsh
。
解释
Mailx - 在 shell 中运行时 - LANG 设置为 .UTF8,将正确识别 UTF8 字符并继续。
在
crontab
中运行时,未设置 LANG,默认为 LANG=C,因为默认情况下 crontab 将仅运行一组受限制的环境变量(取决于系统)。
然后,mailx(或其他程序)将无法识别 UTF8 字符并确定输入包含未知控制字符。
我的问题是UTF8字符,你的问题可能是输入中的其他控制字符。通过
hexdump
或 od -c
运行它,但由于它在常规 shell 中工作正常,我怀疑 LANG 问题。
参考资料:
我也遇到了同样的问题,但上述方法都没有解决问题。移动文件中的额外返回值解决了我的问题:
cat logfile | tr -d \\r | mailx -s'the logfile' to-me@.....
感谢这个论坛:
https://forums.opensuse.org/showthread.php/445955-mailx-creates-unwanted-attachment
确保在脚本中更改此设置
#/bin/sh
替换为
#!/bin/sh
问题来了
您的脚本假设它是从特定目录运行的(请注意,几乎每个路径都是相对路径,而不是绝对路径)。 cron 恰好从另一个目录运行它。
修复电子邮件中出现的文本
mydir=$(dirname "$0") && cd "${mydir}" || exit 1
./opt/bin/analysis.sh > test
mail -s "Today's Weather" [email protected] < /opt/bin/test
解释
$0 是正在执行的 shell 脚本的(可能是相对的)文件名。给定文件名,dirname 命令返回包含该文件名的目录。 因此,该行将目录更改为包含脚本的目录,或者如果 dirname 或 cd 失败则退出并显示错误代码。
或者尝试拥有完整路径,例如
./opt/bin/analysis.sh > test
mail -s "Today's Weather" [email protected] < /opt/bin/test
注意:之前讨论过同样的问题这里
跟进:
尝试删除
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
就我而言,cron 不是 shell 脚本,而是 PHP 脚本(所以我不能放
export LANG
的东西):
0 9 * * * apache php /test/myscript.php | mail -s "CRON - myscript" [email protected]
解决方案:
为了解决相同的问题(内容作为附件而不是正文邮寄),我在 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" [email protected]
注意: 将
LANG=fr_FR.UTF-8
放入 /etc/environment
文件中并重新启动 cron 服务也有效。
参考:
提供的解决方案都不适合我,但如果您尝试发送空消息正文,我找到了解决方法。
由于邮件正文是在空附件中发送的,我注意到这个命令行选项:
--[no-]skip-empty-attachments
skip attachments with empty body
当包含这个论点时,我不再遇到这个问题。