3

My bash script (init.sh) call another script (script.sh) and I want to test the error code from script.sh before doing any further action in init.sh.
I thought about testing it with $?, but it does not work

My init.sh is like the following:

#!/bin/bash
set -e
echo "Before call"
docker run -v $PWD:/t -w /t [command]
if [ $? == 1 ]; then
        echo "Issue"
fi
echo "After call"

I only got the Before call from stdout and not the After call.

I know for a fact that if I execute docker run -v $PWD:/t -w /t [command] alone with wrong arguments, then echo $? will rightly display 1.

I was thinking that I do not catch the exit code from scrip.sh, but from somewhere else.

Any ideas?

2
  • 1
    This is confusing ... you mention script.sh but don't call it in your init.sh. Anyhow, you might try run bash -x init.sh and see what it's actually doing. Commented Sep 29, 2016 at 14:59
  • 1
    With set -e, if the call to docker does set $? to 1, your script will exit before the if statement executes, let alone the final echo call. Commented Sep 29, 2016 at 15:01

3 Answers 3

5

You running the script with set -e. This means that if any command exits with a non zero status, bash will stop executing all subsequent lines. So here, if docker exits with status 1, the conditional that follows will not have a chance to run at all. Try this instead:

#!/bin/bash
set -e
echo "Before call"
if ! docker run -v $PWD:/t -w /t [command]; then
        echo "Issue"
fi
echo "After call"

This runs the command inside the if test which suppresses the effect of set -e I described above and gives you a chance to catch the error. Note this is will also catch all non-zero statuses, not just 1.

Sign up to request clarification or add additional context in comments.

6 Comments

@chepner You are right. In fact, I guess this question itself is an example why.
The question just seems to overlook that set -e was in effect. The actual problems with set -e involve more unexpected exits (or failures to exit).
So, what's the more efficient way? Get rid of the set -e or use the solution from @redneb?
Just get rid of set -e. If you really need the script to exit, you can call exit explicitly (with the appropriate exit status) from within the if statement.
|
1

Bash numeric comparison operator is -eq, and not ==...
So:

#!/bin/bash
set -e
echo "Before call"
docker run -v $PWD:/t -w /t [command]
if [ $? -eq 1 ]; then
        echo "Issue"
fi
echo "After call"

4 Comments

It's somewhat irrelevant; there aren't any values that $?could have that would cause $? -eq 1 and $? = 1 (use = with [, not ==) to behave differently.
@Mornor: why did it fail? Because the command did not exit with -1? Or why? You should echo the value of $?, to test it's value...
Because I set -e, you can check the answer from @redneb
I see. However, the syntax was incorrect in the first place. The solution for you is probably not to use -e flag... :-)
1

set -e is generally a bad idea. Sure, it may seem like a good idea to have your script exit automatically in the event of an unexpected error, but the problem is that set -e and you may have different ideas about what constitutes a fatal error.

Instead, do your own error handling.

#!/bin/bash
echo "Before call"
docker run -v $PWD:/t -w /t [command]
docker_status=$?
if [ $docker_status != 0 ]; then
    echo "docker returned: $docker_status"
    exit $docker_status
fi
echo "After call"

In this simple code, I've somewhat redundantly saved the value of $? to another variable first. This ensures that it is preserved after you start executing other commands that examine, log, or otherwise process the value of $?. Also, I'm logging and exiting here on any non-zero status, not just 1. In theory, you might take different action for an exit status of 1 than for an exit status of 2, but here we take the same log-then-exit action for any error.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.