如果输入过程失败,bash脚本接受登录stdin和电子邮件日志

时间:2016-02-25 20:03:07

标签: bash pipe exit status

我是一个系统管理员,而且我经常遇到这样一种情况:我有一个产生大量输出的脚本或命令,如果命令失败,我只想通过电子邮件发送给我。编写运行命令的脚本非常容易,收集输出并在命令失败时通过电子邮件发送它,但我想我应该能够编写一个命令

1)接受stdin的日志信息 2)等待输入过程退出并查看它的退出状态 3a)如果输入过程干净地退出,则将日志记录输入附加到普通日志文件 3b)如果输入过程失败,请将日志记录输入附加到普通日志,并向我发送电子邮件。

在命令行上看起来像这样:

something_important | mailonfail.sh me@example.com /var/log/normal_log

这样可以很容易地在crontabs中使用。

我无法弄清楚如何让我的脚本等待编写过程并评估该过程如何退出。

只是为了表达清楚,以下是我如何使用包装器来做到这一点:

#! /bin/bash

something_important > output
ERR=$!

if [ "$ERR" -ne "0" ] ; then
  cat something_important | mail -s "something_important failed" me@example.com
fi
cat something_important >> /var/log/normal_log

同样,这不是我想要的,我想写一个脚本和管道命令。

这有意义吗?我该怎么办?我错过了什么吗?

谢谢大家! -Dylan

1 个答案:

答案 0 :(得分:1)

是的,它确实有意义,而且你很接近。

以下是一些建议:

#!/bin/sh

TEMPFILE=$(mktemp)
trap "rm -f $TEMPFILE" EXIT

if [ ! something_important > $TEMPFILE ]; then
  mail -s 'something goes oops' -a $TEMPFILE you@example.net
fi
cat $TEMPFILE >> /var/log/normal.log
  • 我不会使用bashisms所以/ bin / sh很好
  • 使用mktemp(1)
  • 创建临时文件以避免冲突
  • 使用trap在脚本退出时删除文件,通常是否
  • 如果命令失败
  • 然后附上该文件,该文件将嵌入或不首选

    • 如果它是一个大文件你甚至可以gzip它,但附件方法会改变:

      # using mailx
      gzip -c9 $TEMPFILE | uuencode fail.log.gz | mailx -s subject ...
      
      # using mutt
      gzip $TEMPFILE
      mutt -a $TEMPFILE.gz -s ...
      gzip -d $TEMPFILE.gz