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?

  • 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

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.

  • any idea how to make it handle unbound variables set -u;echo $str ? – Aquarius Power Jul 25 '14 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 '14 at 6:49
  • I was working on this answer/question, yep I ended having to use trap ERR – Aquarius Power Jul 25 '14 at 7:52

You can also do this by redirection:

# run_cmd 'error message' cmd -foo "${params[@]}"
run_cmd() {
    local e r m=$1
    exec 6>&1
    e=$("$@" 2>&1 >&6)
    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"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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