Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a helper function:

function error_exit
{
    /opt/aws/bin/cfn-signal ...
    exit 1
}

This helper function is used to signal an error. Here is an example of usage:

/opt/aws/bin/cfn-init -s .. || error_exit 'Failed to run cfn-init'

The cfn-init command takes a lot of parameters which isn't relevant for the question. When the command returns a non-null value and possibly an error message to the error output, I would like to get the error message and include it to the error_exit method as a parameter. Is this possible? If not, how would you implement a helper method in bash which makes it possible to get the source error message?

share|improve this question
    
In the context of CloudFormation's stock templates, from which this looks to derive, also consider setting 'DisableRollback' with --disable-rollback in the CLI tools. Also use cfn-init's -v flag to get verbose output. –  Christopher Jul 23 '12 at 13:22

2 Answers 2

up vote 4 down vote accepted

You can redirect the error output to a file and then retrieve that output:

trap "rm -f /tmp/cfn-error.txt" 0 1 2 3 15
/opt/aws/bin/cfn-init -s ... 2>/tmp/cfn-error.txt ||
    error_exit $(</tmp/cfn-error.txt)

You should always clean up your mess, so don't forget to delete any temp files you create.

share|improve this answer
    
any idea how to make it handle unbound variables set -u;echo $str ? –  Aquarius Power Jul 25 at 2:55
    
Do you mean handle when the shell would exit because of the -u option? In (da)sh, there is trap 0. In bash, there is trap ERR. –  Arcege Jul 25 at 6:49
    
I was working on this answer/question, yep I ended having to use trap ERR –  Aquarius Power Jul 25 at 7:52

You can also do this by redirection:

# run_cmd 'error message' cmd -foo "${params[@]}"
run_cmd() {
    local e r m=$1
    shift
    exec 6>&1
    e=$("$@" 2>&1 >&6)
    r=$?
    exec 6>&-
    ((r)) || return 0
    error_exit "$m" "$e"
}

So you would use:

run_cmd 'Failed to run cfn-init' /opt/aws/bin/cfn-init -s ..

The line: e=$("$@" 2>&1 >&6) first directs stderr to stdout, which in the context of $(..) is the output we're capturing. Then stdout is directed to where it originally went when we started the function.

Of course, you can make error_exit additionally take the exit status, and call it with eg: error_exit "$m" "$r" "$e"

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.