views:

25

answers:

3

I am trying to do validation for every function I call in a script and erroring out the whole script if one function fails.

Looking for the best way to do this. I feel I knew a good way to do it at one time, but can't figure it out again.

I can brute force it, but it's nasty. This is how I can get it to work correctly

    copy_files $1
    if [ "$?" -ne "0" ]; then
            error "Copying files"
            return -1
    fi

This gets pretty ugly since I have a script that goes:

command1 command2 command3

Having to wrap all these commands with returns is not very ideal. :( Please help!

+3  A: 
command1 || (error "Cmd1 fail"; return -1); command2 || (error "Cmd2 fail"; return -1);

etc. etc. The || operator means the next command will only execute if the previous command failed. && is the opposite. The brackets group the commands to run.

Blue Peppers
+1 for `||`, but I'd recommend changing `return -1` to `exit 1` (1 is the standard choice of error code). That lets you define a function called `die` which takes care of the exiting part, then you can write `command1 || die` and `command2 || die` etc. That's a fairly common practice.
David Zaslavsky
I like this...however I am running my script by doing a . ./myscript.sh. If I do a exit 1 in my die, it kills my whole terminal. Any thoughts on how to exit the script without killing my terminal from the script?
bmucklow
A: 

You could do something like this:

good() { 
    return 0;
}

bad() {
    return 5;
}

wrapper() { 
    $1  

    rc=$?

    if [ "$rc" -ne "0" ]; then
            echo "error: $1 returned $rc"
            exit -1
    fi  
}


wrapper bad 
wrapper good

or, if you could pass a list of function, like so:

wrapper() {
    for f in $*; do

        $f 
        rc=$?

        if [ "$rc" -ne "0" ]; then
                echo "error: $f returned ${rc}"
                return -1
        fi
    done
    return 0;
}


wrapper good bad

if [ "$?" -ne "0" ]; then
    #error handling here
    exit -1;
fi
miedwar
+1  A: 

Since you said you want to do this for every command in a script, you could insert

set -e

at the beginning. That call makes the shell exit immediately if any command returns a status code other than 0. (Exceptions: commands that are part of the test in a conditional statement, and those that are followed by && or || and further commands)

David Zaslavsky
If you do this, consider setting PS4 for better tracing. export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: '. Per http://aymanh.com/how-debug-bash-scripts
Charles Merriam