Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question
    
Looks like you want to keep track of access to your server. This is not the best way to set restrictions or logging. An alternative for ls would be find -maxdepth 1 -ls, mv/cp could be replaced by a python/perl script or a combination with tar. Of course, it's possible to place your own binaries on the system and execute them. What would you like to accomplish? –  Lekensteyn Mar 27 '11 at 19:50

4 Answers 4

up vote 1 down vote accepted

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

Since that can get messy, use functions, such as

#!/bin/bash

do_work() {
  mv... || return 1
  cp... || return 1
  return 0
}

report() {
  [ "$1" = "ok" ] && mailx ....
  [ "$1" != "ok" ] && mailx -s "$1" ....
  return 0
}

do_work \
  && report ok 
  || report err

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.)

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

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" me@me.com

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.