Mornor
Mornor

Reputation: 3783

In a bash script, test error code from a called script

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?

Upvotes: 3

Views: 2585

Answers (3)

chepner
chepner

Reputation: 531215

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.

Upvotes: 1

redneb
redneb

Reputation: 23850

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.

Upvotes: 5

MarcoS
MarcoS

Reputation: 17711

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"

Upvotes: 1

Related Questions