NDBoost
NDBoost

Reputation: 10634

Shell Script, When executing commands do something if an error is returned

I am trying to automate out a lot of our pre fs/db tasks and one thing that bugs me is not knowing whether or not a command i issue REALLY happened. I'd like a way to be able to watch for a return code of some sort from executing that command. Where if it fails to rm because of a permission denied or any error. to issue an exit..

If i have a shell script as such:

rm /oracle/$SAPSID/mirrlogA/cntrl/cntrl$SAPSID.ctl;

psuedo code could be something similar to..

rm /oracle/$SAPSID/mirrlogA/cntrl/cntrl$SAPSID.ctl;
if [returncode == 'error']
  exit;
fi

how could i for example, execute that rm command and exit if its NOT rm'd. I will be adapting the answer to execute with multiple other types of commands such as sed -i -e, and cp and umount

edit:

Lets suppose i have a write protected file such as:

$ ls -lrt | grep protectedfile
-rwx------ 1 orasmq  sapsys         0 Nov 14 12:39 protectedfile

And running the below script generates the following error because obviously theres no permissions..

rm: remove write-protected regular empty file `/tmp/protectedfile'? y
rm: cannot remove `/tmp/protectedfile': Operation not permitted

Here is what i worked out from your guys' answers.. is this the right way to do something like this? Also how could i dump the error rm: cannot remove /tmp/protectedfile': Operation not permitted` to a logfile?

#! /bin/bash
function log(){
    //some logging code, simply writes to a file and then echo's out inpit
}
function quit(){
   read -p "Failed to remove protected file, permission denied?"
   log "Some log message, and somehow append the returned error message from rm"
   exit 1;
}

rm /tmp/protectedfile || quit;

Upvotes: 1

Views: 1195

Answers (3)

Salandur
Salandur

Reputation: 6453

Usualy some would use a command like this:

doSomething.sh
if [ $? -ne 0 ]
then
    echo "oops, i did it again"
    exit 1;
fi

B.T.W. searching for 'bash exit status' will give you already a lot of good results

Upvotes: 0

Olivier Dulac
Olivier Dulac

Reputation: 3791

a possibility: a 'wrapper' so that you can retrieve the original commands stderr |and stdout?], and maybe also retry it a few times before giving up?, etc.

Here is a version that redirects both stdout and stderr

Of course you could not redirect stdout at all (and usually, you shouldn't, i guess, making the "try_to" function a bit more useful in the rest of the script!)

export timescalled=0  #external to the function itself

try_to () {
    let "timescalled += 1"  #let "..." allows white spaces and simple arithmetics
    try_to_out="/tmp/try_to_${$}.${timescalled}" 
        #tries to avoid collisions within same script and/or if multiple script run in parrallel
    zecmd="$1" ; shift ;
    "$1" "$@" 2>"${try_to_out}.ERR" >"${try_to_out}.OUT"
    try_to_ret=$?
    #or: "$1" "$@" >"${try_to_out}.ERR" 2>&1  to have both in the same one
    if [ "$try_to_ret" -ne "0" ]
    then  log "error $try_to_ret while trying to : '${zecmd} $@' ..." "${try_to_out}.ERR" 
            #provides custom error message + the name of the stderr from the command
          rm -f "${try_to_out}.ERR" "${try_to_out}.OUT" #before we exit, better delete this
          exit 1 #or exit $try_to_ret ?
    fi
    rm -f "${try_to_out}.ERR" "${try_to_out}.OUT"
}

it's ugly, but could help ^^

note that there are many things that could go wrong: 'timecalled' could become too high, the tmp file(s) could not be writable, zecmd could contain special caracters, etc...

Upvotes: 0

Isvara
Isvara

Reputation: 3463

If I understand correctly what you want, just use this:

rm blah/blah/blah || exit 1

Upvotes: 1

Related Questions