1

It seems that somehow my knowledge of bash is not really great as after so many years I discover something weird:

#!/bin/bash
set -e
# so we expect to exit with error code on first failure

false || true
echo "ok, expected to reach this place"

false && true
echo "why am I here?"

Now, I am asking this because I found this why trying to use the gerrit cherry pick code snippet inside a bash script, and to my surprise it failed to exit when the first command failed.

 set -e
 git fetch https://review.gerrithub.io/xxx/123 refs/changes/01/123456/666 && git cherry-pick FETCH_HEAD

The code above is provided by gerrit as so you can easily copy/paste it and the && is supposed to prevent running the 2nd command when the first fais. Still when this code is put inside a bash script using set -e, it fails to return an exit code and your script continues instead of stopping.

Obviously I could replace the && with a ; or new-line but that's not the point. Isn't it possible to make this piece of code work the same in both cases?

sorin
  • 161,544
  • 178
  • 535
  • 806

1 Answers1

3

It's documented to work this way:

-e

Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists), or a compound command (see Compound Commands) returns a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.

In your code, you'll have to use a longer form:

set -e
if git fetch https://review.gerrithub.io/xxx/123 refs/changes/01/123456/666; then
    git cherry-pick FETCH_HEAD
else
    false
fi

Or, do this:

git fetch ... && git cherry-pick ... || false

That will exit if:

  1. the fetch fails, or
  2. the fetch succeeds but the cherry-pick fails.
glenn jackman
  • 238,783
  • 38
  • 220
  • 352