我有一个适用于 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 上失败的原因有以下三个:
MAILTO=
抛出语法错误*/15
抛出语法错误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
:那是不安全的。