checkrun.sh - Error Notification for .timer Units

Posted on Fri 07 August 2015

I'm currently migrating my CRON scripts to systemd .timer units. Unfortunately systemd does not have the feature of sending mails for failed units, containing the output of the failed command.

Enter checkrun.sh, a simple wrapper script that does exactly this job: executing a given command, capturing its potential output and sending a notification mail containing the former on error.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/bin/bash

# defaults
MAILER="sendmail"
MAILTO="$USER"
VERBOSE=0

# usage information
function print_usage() {
    echo "usage: $0 [OPTIONS] COMMAND"
    echo "options:"
    echo "    -s CMD     use CMD as mailer (default: sendmail)"
    echo "    -m MAILTO  set recipient for notification mail (default: \$USER)"
    echo "    -v         send command output even on exit code 0"
    echo "    -h         display this usage information"
}

# parse cmdline options
while getopts ":s:m:vh" OPT; do
    case $OPT in
        s)
            MAILER="$OPTARG"
            ;;
        m)
            MAILTO="$OPTARG"
            ;;
        v)
            VERBOSE=1
            ;;
        h)
            print_usage
            exit 0
            ;;
        \?)
            echo "Invalid option: -$OPTARG." >&2
            exit 1
            ;;
        :)
            echo "Option -$OPTARG requires an argument." >&2
            exit 1
            ;;
    esac
done
shift $(( $OPTIND - 1 ))

# check for COMMAND
if [ -z "$1" ]; then
    echo "error: missing argument."
    print_usage
    exit 1
fi

# execute COMMAND, capture output
LOG="$(mktemp)"
$1 &> "$LOG"
ERR=$?

# evaluate return value
if [ $ERR -ne 0 ]; then
    echo -e "Subject: '$1' FAILED ($ERR)\r\n" | cat - "$LOG" | $MAILER "$MAILTO"
    cat "$LOG"
    exit $ERR
fi

# notify if output was given and verbose mode selected
if [ $VERBOSE -eq 1 ] && [ $(wc -l "$LOG" | cut -d ' ' -f 1) -gt 0 ]; then
    echo -e "Subject: '$1'\r\n" | cat - "$LOG" | $MAILER "$MAILTO"
fi

# clean up
rm -f "$LOG"

exit 0

(a bit too simple, therefore not git-contained, yet)

tags: code, bash, systemd, cron, wrapper | category: projects