errors=3
cbase=$HOME/sysd-mail-once-state
+to=root
case "$1" in
- -h|--help)
- cat <<EOF
-Usage: sysd-log-once [-ERRORS] SERVICE COMMAND [ARGS...]
-For systemd timers, email on repeated failure & success after failure.
+ -h|--help)
+ cat <<EOF
+Usage: sysd-mail-once [-t TO_ADDRESS] [-ERRORS] SERVICE COMMAND [ARGS...]
+For systemd timers, email (with exim) on repeated failure & success after failure.
In the service triggered by the timer, prepend this script to the ExecStart.
The email will contain the service's logs for the last ERRORS runs.
-ERRORS: ERRORS is the number of failurs to accumulate before mailing the error.
Default is 3.
EOF
- exit 0
- ;;
- -[0-9]*)
- errors=${1#-}
- shift
- ;;
+ exit 0
+ ;;
+ -[0-9]*)
+ errors=${1#-}
+ shift
+ ;;
+ -t)
+ to="$2"
+ shift 2
+ ;;
esac
service=$1
shift
-c=$cbase/$service
+c=$cbase/$service # c for command file path base
glob="$c[0-9]*"
arr=($glob); file="${arr[0]}"; [[ $glob != "$file" ]] || file=
-u=${USER:-root}
[[ -d $cbase ]] || mkdir -p $cbase
if [[ ! $file ]]; then
- cursor=$(journalctl --show-cursor -qn0|sed 's/^\s*--\scursor:\s*//')
+ cursor=$(journalctl --show-cursor -qn0|sed 's/^\s*--\scursor:\s*//')
fi
-if "$@"; then
- if [[ $file ]]; then
- rm -f $file
- if [[ $file == $c$errors ]]; then
- echo | mail -s "$HOSTNAME: $service success" $u@localhost
- fi
+
+code=0
+"$@" || code=$?
+if (( code )); then
+ send_mail=false
+ if [[ $file ]]; then
+ i=${file#$c}
+ if (( i < errors )); then
+ new_file=$c$((i+1))
+ mv $file $new_file
+ file=$new_file
+ if [[ $file == $c$errors ]]; then
+ send_mail=true
+ fi
+ fi
+ else
+ file=${c}1
+ printf "%s\n" "$cursor" >$file
+ if (( errors == 1 )); then
+ send_mail=true
fi
-else # $@ failed
- if [[ $file ]]; then
- i=${file#$c}
- if (( i < errors )); then
- new_file=$c$((i+1))
- mv $file $new_file
- file=$new_file
- if [[ $file == $c$errors ]]; then
- journalctl -u $service.service --after-cursor=$(<$file) | \
- mail -s "$HOSTNAME: $service failure" $u@localhost
- fi
- fi
- else
- file=${c}1
- printf "%s\n" "$cursor" >$file
+ fi
+ if $send_mail; then
+ exim -odf -t <<EOF
+To: $to
+From: $USER@$(hostname -f)
+Subject: $HOSTNAME: $service exit code: $code
+
+$(journalctl -u $service.service --after-cursor=$(<$file))
+EOF
+ fi
+else
+ if [[ $file ]]; then
+ rm -f $file
+ if [[ $file == $c$errors ]]; then
+ exim -odf -t <<EOF
+To: $to
+From: $USER@$(hostname -f)
+Subject: $HOSTNAME: $service success
+
+EOF
fi
+ fi
fi