I've a script which do. ls , cp, mv
I want if any of the command fail this should alert over email as well as after successful competition. Any idea? I can adjust email alert but want to know how to check for errors and successful attempt.
Bash doesn't have any built in alerting for this stuff, you need to write it into your script by checking the $? variable (holds the exit code of the last run command) and taking an action on it.
A dead simple check that emails would look like:
if [ $? -ne 0 ]
then
<send me email however you want to about failure>
else
<send me email about success how ever you want>
fi
Be sure to check your command documentation to make sure successful execution sets an exit code of 0.
You can have a series of commands continue to execute until "failure" by using "&&" to run the commands in succession; each command returns "true", causing the following command to run. Then use "||" to run a command upon failure, such as:
#!/bin/bash
cp foo bar \
&& mv bar bar{,.bak} \
&& echo "good so far" \
&& ls file123 | tee -a /tmp/msg.txt \
&& mailx -u user -s "success" -f /tmp/msg.txt \
|| mailx -u user -s "failure" -f ~/err.txt
Further, continuing from the above example, you can add blanket rules via a 'trap' in the script that will always execute certain commands if any type of error status is returned at any point in the script (including receiving a control-c (interrupt) signal while the script is running):
#!/bin/bash
tmp=/tmp/msg.$$.txt
# Cleanup: delete tmp files on exit. On any error, trap and exit... then cleanup
trap 'echo "cleaning up tmpfiles..." && rm $tmp >/dev/null 2>&1' 0
trap "exit 2" 1 2 3 15
...
do_work && exit 0
(Disclaimer... commands shown above are general pseudo-code, and just typed from memory without running them. Typos surely exist.)
You use a mailwrap command wrapper, one which takes some options specifying who to mail to, before running the command which is its parameter. The mailwrap command only sends email if there's output, or if the script failed. There are many variants out there, and they're good exercises to write yourself if you don't like those you find.
On the #! line of the script itself, you use -e, so that any command pipeline which fails causes the script to abort at that point. You might also use -u, to abort on using an unset variable.
To have a failing command not abort the script, you append || true, read as "or true", so that failure doesn't matter. (More idiomatically, || : which is the same thing).
If you want to see exactly where a normally-silent command failed, you use a mailwrap command which doesn't send email just because of output to stderr and then you use -v on the shell #! line, to trace commands as they're about to be run.
Bash doesn't have any built in alerting for this stuff, you need to write it into your script by checking the
$?
variable (holds the exit code of the last run command) and taking an action on it.A dead simple check that emails would look like:
Be sure to check your command documentation to make sure successful execution sets an exit code of 0.
You can have a series of commands continue to execute until "failure" by using "&&" to run the commands in succession; each command returns "true", causing the following command to run. Then use "||" to run a command upon failure, such as:
Since that can get messy, use functions, such as
Further, continuing from the above example, you can add blanket rules via a 'trap' in the script that will always execute certain commands if any type of error status is returned at any point in the script (including receiving a control-c (interrupt) signal while the script is running):
(Disclaimer... commands shown above are general pseudo-code, and just typed from memory without running them. Typos surely exist.)
You use a mailwrap command wrapper, one which takes some options specifying who to mail to, before running the command which is its parameter. The mailwrap command only sends email if there's output, or if the script failed. There are many variants out there, and they're good exercises to write yourself if you don't like those you find.
On the
#!
line of the script itself, you use-e
, so that any command pipeline which fails causes the script to abort at that point. You might also use-u
, to abort on using an unset variable.To have a failing command not abort the script, you append
|| true
, read as "or true", so that failure doesn't matter. (More idiomatically,|| :
which is the same thing).If you want to see exactly where a normally-silent command failed, you use a mailwrap command which doesn't send email just because of output to stderr and then you use
-v
on the shell#!
line, to trace commands as they're about to be run.Or pipe the output of the script into a mail whatever the result is until you're happy it's working.
Something like:
(cat $resultofscript) | mailx -s "Subject" [email protected]