-
Notifications
You must be signed in to change notification settings - Fork 1
/
send-mail-on-failure-or-output
executable file
·100 lines (89 loc) · 2.65 KB
/
send-mail-on-failure-or-output
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash
# Run a command and send a mail if the command fails or produces output. Use
# --ignore_exit_status to only send mail if output is produced.
# Redirects stdout and stderr, so if your command or caller does that it won't
# work properly.
set -e -f -u -o pipefail
usage() {
printf "%s [OPTIONS] EMAIL_ADDRESS command args\\n" "$0"
printf "OPTIONS: --ignore_exit_status, --only_on_failure\\n"
printf "Cannot use --ignore_exit_status and --only_on_failure together\\n"
}
main() {
local IGNORE_EXIT_STATUS=0 ONLY_ON_FAILURE=0
while :; do
case "${1:-}" in
--ignore_exit_status)
IGNORE_EXIT_STATUS=1
shift
;;
--only_on_failure)
ONLY_ON_FAILURE=1
shift
;;
--help)
usage
return 0
;;
--*)
printf "Unrecognised option: %s\\n" "$1" >&2
usage >&2
return 1
;;
*)
break
esac
done
readonly IGNORE_EXIT_STATUS ONLY_ON_FAILURE
if [[ "${IGNORE_EXIT_STATUS}" -eq 1 && "${ONLY_ON_FAILURE}" -eq 1 ]]; then
printf "Cannot use both --ignore_exit_status and --only_on_failure\\n" >&2
return 1
fi
if [[ "$#" -eq 0 ]]; then
printf "No email address given!\\n" >&2
usage >&2
return 1
fi
local DESTINATION="$1"
shift
readonly DESTINATION
if [[ "$#" -eq 0 ]]; then
printf "No command to run!\\n" >&2
usage >&2
return 1
fi
local EXIT_STATUS=0
"$@" > "${OUTPUT_FILE}" 2>&1 || EXIT_STATUS="$?"
local SEND_MAIL=0
if [[ "${EXIT_STATUS}" -ne 0 && "${IGNORE_EXIT_STATUS}" -eq 0 ]]; then
SEND_MAIL=1
fi
if [[ -s "${OUTPUT_FILE}" ]]; then
if [[ "${ONLY_ON_FAILURE}" -eq 1 ]]; then
if [[ "${EXIT_STATUS}" -ne 0 ]]; then
SEND_MAIL=1
fi
else
SEND_MAIL=1
fi
fi
# Support overriding the subject prefix to make testing idempotent.
local SUBJECT="${SUBJECT_PREFIX:-${USER}@${HOSTNAME}}: $*"
if [[ "${SEND_MAIL}" -eq 1 ]]; then
(printf "Exit status: %s\\nOutput:\\n" "${EXIT_STATUS}";
cat "${OUTPUT_FILE}"
) | mail -s "${SUBJECT}" "${DESTINATION}"
printf "%s -- %s\n" "${DESTINATION}" "${SUBJECT}" \
>> "${HOME}/tmp/logs/send-mail-on-failure-or-output.log"
fi
return "${EXIT_STATUS}"
}
# Set this up unconditionally so it is set up once and cleaned up once,
# including during testing.
OUTPUT_FILE="$(mktemp -t send-mail-on-failure-or-output.XXXXXXXXXXXXXXXX)"
trap 'rm -f "${OUTPUT_FILE}"' EXIT
# Only run main if being executed directly; do nothing if sourced for testing.
# Use basename so that it can be run as 'bash -x ./program ...'.
if [[ "$(basename "${BASH_SOURCE[0]}")" == "$(basename "${0}")" ]]; then
main "$@"
fi