Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash run command without exiting on error and tell me its exit code

Tags:

bash

shell

From a bash script I want to run a command which might fail, store its exit code in a variable, and run a subsequent command regardless of that exit code.

Examples of what I'm trying to avoid:

Using set:

set +e  # disable exit on error (it was explicitly enabled earlier)
docker exec $CONTAINER_NAME npm test
test_exit_code=$?  # remember exit code of previous command
set -e  # enable exit on error
echo "copying unit test result file to host"
docker cp $CONTAINER_NAME:/home/test/test-results.xml .
exit $test_exit_code

Using if:

if docker exec $CONTAINER_NAME npm test ; then
    test_exit_code=$?
else
    test_exit_code=$?
fi
echo "copying unit test result file to host"
docker cp $CONTAINER_NAME:/home/test/test-results.xml .
exit $test_exit_code

Is there a semantically straightforward way to tell bash "run command without exiting on error, and tell me its exit code"?

The best alternative I have is still confusing and requires comments to explain to subsequent developers (it's just a terser if/else):

docker exec $CONTAINER_NAME npm test && test_exit_code=$? || test_exit_code=$?
echo "copying unit test result file to host"
docker cp $CONTAINER_NAME:/home/test/test-results.xml .
exit $test_exit_code
like image 403
Vladimir Kornea Avatar asked Apr 06 '26 16:04

Vladimir Kornea


1 Answers

I believe you could just use the || operator? Which is equivalent to an "if − else" command.

Would the following address your use case? (otherwise feel free to comment!)

set -e  # implied in a CI context
exit_status=0
docker exec "$CONTAINER_NAME" npm test || exit_status=$?
docker cp "$CONTAINER_NAME:/home/test/test-results.xml" .
exit "$exit_status"

or more briefly:

set -e  # implied in a CI context
docker exec "$CONTAINER_NAME" npm test || exit_status=$?
docker cp "$CONTAINER_NAME:/home/test/test-results.xml" .
exit "${exit_status:-0}"

As an aside, if you are not interested in this exit status code, you can also do something like this:

set -e  # implied in a CI context
docker exec "$CONTAINER_NAME" npm test || :
docker cp "$CONTAINER_NAME:/home/test/test-results.xml" .

For more details on the || : tip, see e.g. this answer on Unix-&-Linux SE:
Which is more idiomatic in a bash script: || true or || :?

like image 92
ErikMD Avatar answered Apr 08 '26 06:04

ErikMD