Ind*_*ial 46 shell bash schedule cron
我最终通过一个 shell 脚本为我的数据设置了一个现实的备份计划,由 cron 以紧密的时间间隔处理。不幸的是,每次执行 CRON 时,我都会收到空电子邮件,而不仅仅是在出现问题时。
是否可以仅在出现问题时让 CRON 发送电子邮件,即。我TAR没有按预期执行?
这是目前我的 crontab 的设置方式;
0 */2 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com
Run Code Online (Sandbox Code Playgroud)
非常感谢!
Cak*_*mox 60
理想情况下,您希望备份脚本在一切按预期进行时不输出任何内容,并且仅在出现问题时才产生输出。然后使用 MAILTO 环境变量将脚本生成的任何输出发送到您的电子邮件地址。
MAILTO=email@example.com
0 */2 * * * /bin/backup.sh
Run Code Online (Sandbox Code Playgroud)
如果您的脚本通常会产生输出但您在 cron 中不关心它,只需将它发送到 /dev/null 并且只有当某些内容写入 stderr 时它才会通过电子邮件发送给您。
MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Run Code Online (Sandbox Code Playgroud)
小智 31
使用cronic包装脚本看起来是个好主意;要使用它,您不必更改脚本。
代替:
0 1 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com
Run Code Online (Sandbox Code Playgroud)
做:
MAILTO=email@example.com
0 1 * * * cronic /bin/backup.sh
Run Code Online (Sandbox Code Playgroud)
简单的说; 如果一切顺利(退出状态 0),它将无声运行,但如果不是,它将详细报告,并让 cron 处理邮件报告。
有关https://habilis.net/cronic/ 的更多信息。
这是我多年来成功使用的另一种变体 - 捕获输出并仅在出现错误时打印出来,触发电子邮件。这不需要临时文件,并保留所有输出。重要的部分是2>&1将 STDERR 重定向到 STDOUT。
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"
Run Code Online (Sandbox Code Playgroud)
(也可以通过为整个crontab文件设置MAILTO=xxxx来更改地址)
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address
Run Code Online (Sandbox Code Playgroud)
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }
Run Code Online (Sandbox Code Playgroud)
这适用于简单的命令。如果您正在处理复杂的管道 ( find / -type f | grep -v bla | tar something-or-other),那么最好将命令移动到脚本中并使用上述方法运行脚本。原因是如果管道的任何部分输出到 STDERR,您仍然会收到电子邮件。
小智 5
这是一个非常常见的问题,现在(2021 年),最好使用moreutils包中的“chronic”来解决,它正是为此目的而完成的。大多数 linux/bsd 发行版中都提供了该软件包。
chronic runs a command, and arranges for its standard out and standard error to only be displayed if the command fails (exits nonzero or crashes). If the command succeeds, any extraneous output will be hidden.
A common use for chronic is for running a cron job. Rather than trying to keep the command quiet, and having to deal with mails containing accidental output when it succeeds, and not verbose enough output when it fails, you can just run it verbosely always, and use chronic to hide the successful output.
0 1 * * * chronic backup # instead of backup >/dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)