12

I'd like to write a simple script that alerts me if a log changes. For this I'm using grep to find the lines I'm interested in. Right now it works like this:

grep line /var/log/file | mail -s Log email@domain.tld

Problem is that this sends a mail even if no matching lines are found. The mail utility from GNU Mailutils seems to have no switch telling it to drop mails that have an empty body.

Is there a quick and easy way to do so?

Colin 't Hart
  • 283
  • 2
  • 16
cdecker
  • 431
  • 2
  • 5
  • 17

3 Answers3

14
output=$(grep line /var/log/file); [[ -n "$output" ]] && mail -s Log email@domain.tld

Or you can make this into a cron job and then if it produces any output it will email the users. You can edit the /etc/aliases file (and then run newaliases command) to send mail to address not on the box.

Ex of cron entry (You won't be able to set the subject line thogh

1 0 * * *  grep line /var/log/file

Or you can get the ifne utility - This is probably what you want

grep line /var/log/file | ifne mail -s Log email@domain.tld

The ifne command it availabe from the epel repo for centos and RHEL. I can't find a link to the man page online but there it is

ifne(1)
ifne(1)

NAME ifne - Run command if the standard input is not empty

SYNOPSIS ifne [-n] command

DESCRIPTION ifne runs the following command if and only if the standard input is not empty.

OPTIONS -n Reverse operation. Run the command if the standard input is emp- ty.

          Note  that  if  the  standard  input  is not empty, it is passed
          through ifne in this case.

EXAMPLE find . -name core | ifne mail -s "Core files found" root

AUTHOR Copyright 2008 by Javier Merino

   Licensed under the GNU GPL

                              2008-05-01                           ifne(1)
Bill Weiss
  • 10,782
  • 3
  • 37
  • 65
ckliborn
  • 2,750
  • 4
  • 24
  • 36
  • 2
    Note that grep will exit non-0 if it generates no output, so you could do: output=$(grep line /var/log/file) && echo "$output" | mail -s Log user@example.com – Sean Reifschneider Jan 15 '12 at 03:16
  • Also, your suggested command doesn't send "$output" to the mail command. :-) – Sean Reifschneider Jan 15 '12 at 03:16
  • I would suggest editing the answer to include the proposed solution by @Sean Reifschneider – Basil A Apr 11 '16 at 20:23
  • FYI `ifne` is found in the `moreutils` package in ubuntu. Unfortunately that package also brings in `parallel` which conflicts with the `parallel` command from the `parallel` package. – artfulrobot Jun 11 '19 at 09:25
14

"man mail" tells me that the argument -E stopps sending mails if body is empty. works fine for me.

-E

If an outgoing message does not contain any text in its first or only message part, do not send it but discard it silently, effectively setting the skipemptybody variable at program startup. This is useful for sending messages from scripts started by cron(8).

user9517
  • 114,104
  • 20
  • 206
  • 289
wolxXx
  • 271
  • 2
  • 6
  • 3
    On Ubuntu 12.04, GNU Mailtools 2.1 is installed, and the "-E" option for "mail" there is a shorthand for --exec. It does not contain an "empty body" option. – Mark Stosberg Mar 13 '13 at 14:50
  • 3
    @MarkStosberg: Ubuntu has multiple alternative packages providing a `mail` or `mailx` command. The `bsd-mailx` and `heirloom-mailx` packages both provide a `mailx` with the `-E` option described here. – Smylers Oct 28 '15 at 16:02
  • 1
    Worked for me on CentOS 6.5: `grep "find me" /var/log/something | mail -s "That text you were looking for is now in the logs" -E mail@example.com` – user2208096 Aug 21 '17 at 18:37
3

See https://unix.stackexchange.com/a/100720/27458

Just use ifne:

grep line /var/log/file | ifne mail -s Log email@domain.tld