satisfy shellcheck
[log-quiet] / sysd-mail-once
index 32aa02d2dbd5911c72656b1b5f39595acfc7c1d6..2c9d0263748e9b715acddb5bf3c0d57d28bb1dd9 100755 (executable)
@@ -1,5 +1,12 @@
 #!/bin/bash
-# Copyright (C) 2016 Ian Kelling
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
 
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,6 +21,7 @@
 # limitations under the License.
 
 
+
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
@@ -22,6 +30,7 @@ tmp=(~)
 cbase="${tmp[0]}/sysd-mail-once-state"
 to=root
 dryrun=false
+print_all=false
 while [[ $1 == -* ]]; do
   case "$1" in
     -h|--help)
@@ -40,6 +49,7 @@ Stores error counts in $cbase
 -ERRORS         ERRORS is the number of failurs to accumulate before mailing the error.
                 Default is 3.
 
+-a              Email the logs of all errors intead of just the last one.
 -t TO_ADDRESS   Address to email about errors
 -n              Dry run. Execute command but only print out what we would do in response.
 EOF
@@ -48,6 +58,9 @@ EOF
     -[0-9]*)
       errors=${1#-}
       ;;
+    -a)
+      print_all=true
+      ;;
     -t)
       to="$2"
       shift
@@ -91,18 +104,18 @@ mi() {
   fi
 }
 e() {
-  printf "dryrun: %s\n" "$*"
+  if $dryrun; then
+    printf "dryrun: %s\n" "$*"
+  fi
 }
 
 c=$cbase/$service # c for command file path base
 
-if $dryrun; then
-  e "c=$c"
-fi
+e "c=$c"
 
 glob="${c}[0-9]*"
 arr=($glob); file="${arr[0]}"; [[ $glob != "$file" ]] || file=
-if [[ $dryrun && $file ]]; then
+if [[ $file ]]; then
   e "file=$file"
 fi
 
@@ -110,14 +123,12 @@ if ! [[ -d $cbase ]]; then
   mkdir -p $cbase
 fi
 
-if [[ ! $file ]]; then
-  cursor=$(journalctl --show-cursor -qn0|sed 's/^\s*--\scursor:\s*//')
-fi
 
 code=0
 "$@" || code=$?
 if (( code )); then
   send_mail=false
+  cursor=$(journalctl --show-cursor -qn0|sed 's/^\s*--\scursor:\s*//')
   if [[ $file ]]; then
     i=${file#"$c"}
     if (( i < errors )); then
@@ -126,6 +137,12 @@ if (( code )); then
       file=$new_file
       if [[ $file == $c$errors ]]; then
         send_mail=true
+      else
+        if $dryrun; then
+          printf "dryrun: appending to file $file: %s\n" "$cursor"
+        else
+          printf "%s\n" "$cursor" >>$file
+        fi
       fi
     fi
   else
@@ -140,13 +157,18 @@ if (( code )); then
     fi
   fi
   if $send_mail; then
+    if $print_all; then
+      cursor=$(head -n1 $file)
+    else
+      cursor=$(tail -n1 $file)
+    fi
     echo "sysd-mail-once: emailing on $errors errors. exit code: $code"
     mi exim -odf -t <<EOF
 To: $to
 From: $(id -u -n)@$(hostname -f)
 Subject: $HOSTNAME: $service exit code: $code
 
-$(journalctl -u $service.service --after-cursor="$(<$file)")
+$(journalctl -u $service.service --after-cursor="$cursor")
 EOF
   fi
 else