POSIX(或便携式)方式从 crontab 转发电子邮件

POSIX(或便携式)方式从 crontab 转发电子邮件

我有一个适用于 IRIX/Linux/macOS/FreeBSD 的安装程序/更新程序脚本,我想将其兼容性扩展到 Solaris。

我已经修复了一些不符合 POSIX 标准的部分,除了crontab如下生成的部分:

printf '%s\n' [email protected] '*/15 * * * * /path/cmd' | crontab -
# crontab -l # (on Linux/macOS/FreeBSD)
[email protected]
*/15 * * * * /path/cmd

笔记: /path/cmd除非检测到问题,否则很安静

该代码在 Solaris 上失败的原因有以下三个:

  1. MAILTO=抛出语法错误
  2. */15抛出语法错误
  3. crontab -尝试打开名为的文件-

我解决了#2#3和:

printf '%s\n' '0,15,30,45 * * * * /path/cmd' | crontab
# crontab -l
0,15,30,45 * * * * /path/cmd

现在我不知道如何转换该MAILTO=部分。从 转发电子邮件的 POSIX 方式是什么crontab


选定的解决方法:

谢谢@ilkkachu@Gilles'SO-stopbeingevil'指针,这就是我决定的方式仿真crontab 的MAILTO行为以符合 POSIX 的方式进行:

# crontab -l
0,15,30,45 * * * * out=$(/path/cmd 2>&1); [ -n "$out" ] && printf \%s\\n "$out" | mailx -s "Cron <$LOGNAME@$(uname -n)>" [email protected]

但是,这个解决方案有一个潜在的问题:如果printf不是一个内置的 shell输出太大,那么它会失败并出现Argument list too long类似的错误。

答案1

请注意,即使在受支持的情况下,这MAILTO对于软件安装程序也没有好处,因为它是一项全局设置:它将应用于 crontab 中的所有条目,而不仅仅是软件添加的条目。

如果您希望软件将电子邮件发送到不同的地址,则需要在自己的代码中进行处理。这意味着您需要自己处理退出状态和空输出的逻辑。

这是一些实现此逻辑的未经测试的代码。用空格替换换行符(或直接删除它们),将它们放在 crontab 文件中的一行上。

out=$(mktemp) &&
/path/cmd >"$out" 2>&1;
status=$?;
if [ "$status" -ne 0 ] || [ -s "$out" ]; then
  mailx -s "/path/cmd exited with status $status" [email protected] <"$out";
fi;
rm -- "$out";

该代码仅使用 POSIX 功能以及广泛可用的mktemp。不幸的是,它在 IRIX 上不可用。如果 IRIX 有符合 POSIX 标准的 m4,你可以用它来实现mktemp。作为后备方案,您可以将临时文件存储在用户主目录下的某个位置,或者存储在只有其他目录可以写入的其他目录中。不要在共享目录中创建具有可预测名称的临时文件,例如/tmp那是不安全的

相关内容