Daniel Widdis
Daniel Widdis

Reputation: 9111

When is the use of "|| true" needed in bash?

I use Travis CI to do unit testing for my open source project. While configuring my .travis.yml file I've seen examples on several other projects, and some inconsistent use of || true following some conditionals in the script. I have seen them in two formats.

When the statement is executed as a conditional, I understand the need for || true to ensure the command returns "success" and allows the script to continue. A non-match on the name would be false, omit execution of later commands after &&, but eventually return successful after || true.

- '[ "${TRAVIS_OS_NAME}" = "osx" ] && brew install ant || true'

However, I have also seen the conditional applied after if ... fi conditionals, such as this example:

- if [ "${TRAVIS_CPU_ARCH}" == "arm64" ]; then 
    sudo apt-get install openjdk-11-jdk libltdl-dev;
    export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-arm64;
    export PATH=$JAVA_HOME:$PATH; 
  fi || true

My own testing indicates it makes no difference whether that's included or not. For example, this conditional does not stop the test, even when it evaluates to false. For example:

if [ "${TRAVIS_BRANCH}" == "coverity_scan" ]; then exit 0; fi

Travis produces this output, showing a "true" result:

The command "if [ "${TRAVIS_BRANCH}" == "coverity_scan" ]; then exit 0; fi" exited with 0.

The script continues past this point without complaint, on the "master" branch. My assessment is that an if [ false ] then; ...; fi conditional either returns true, or is effectively a no-operation, and it's not needed.

Is || true necessary, or even useful, to add after a if ... fi conditional in the case where the conditional is false? (Assume I want the script to fail if the conditional is true and a statement inside it fails.)

Upvotes: 0

Views: 272

Answers (1)

KamilCuk
KamilCuk

Reputation: 141020

When is the use of “|| true” needed in bash?

When the script is executed in an environment when it's execution will stop if any of the expressions will return with nonzero exit status. Such examples are with set -e or like your example inside ci/cd tools.

The chain:

false && true
#  $? is 1

will exit with nonzero exit status. I find people use || true or shorter ||: in such scripts to make the commands lists with && exit with zero status even if it one of the commands fail. Typically:

 [ -e "env_file" ] && . "env_file" ||:

I have also seen the conditional applied after if ... fi conditionals

This certain usage you showed seems to be some left-over or inserted by some over-protective programmer. export always returns with a zero exit status.

If the expression in if will exit with zero exit status then the if body will execute. The exit status of if command is the exit status of last command executed (as usuall in groups).

if true; then
   dont care;
   dont care;
   false
fi 
#  exits with exit status of false

Thus programmer can insert || true to make the exit status of if expression to zero.

My assessment is that an if [ false ] then; ...; fi

[ false ] returns with zero exit status, because the string false has nonzero length. I think you meant to execute the command false with if false.

Is || true necessary, or even useful, to add after a if ... fi conditional in the case where the conditional is false?

If there are no ifelse block or else block that get executed like in the code presented, then no, if will return with success. I think a qoute from manual would be best bash manual Conditional Constructs if:

if

... The return status [of if] is the exit status of the last command executed, or zero if no condition tested true.

Upvotes: 2

Related Questions