The right way to test exit codes in Bash

· Thomas Taylor

In this article, we’ll go over how to properly test exit codes in Bash scripts.

Testing exit codes with $?

When I first started writing Bash, I often wrote the following code to test whether a program’s execution was successful:

2if [ "$?" -eq 0 ]; then
3    echo "It worked!"

However, this introduces complexity in the flow of the script. For example, one minor mistake like adding en echo statement:

2echo "some_command"
3if [ "$?" -eq 0 ]; then
4    echo "It worked!"

can introduce unintended side effects that are not immediately clear. In this case, the echo statement’s exit status is 0 and skips the if conditional.

Therefore, if status codes are used as true/false indictators, do not use this method

Testing for successful exit codes

For the majority of my use cases, I need to evaluate whether a program’s execution is or is not successful.

Using the following syntax clearly informs readers what is happening:

1if some_command; then
2    echo "It worked!"

If some_command executes correctly, echo "It worked!".

Testing for failed exit codes

Similarly, we can test for failed exit codes by negating the if statement:

1if ! some_command; then
2    echo "It did not work!"

If some_command executes incorrectly, echo "It did not work!"

Testing for specific exit codes

If your use case requires testing for specific exit codes, then I recommend collecting the exit status on the same line and using a case statement.

For example:

1some_command; some_command_exit_code=$?
2case $some_command_exit_code in
3    0) echo "It worked!" ;;
4    *) echo "It did not work!" ;;

Using a case statement allows us to control the flow in an easy-to-digest manner.

After all, code maintainability should be prioritized.


Reply to this post by email ↪