Subject: Re: [PATCH 06/12] t: prepare execution of potentially failing commands for `set -e`

From: Jeff King <[email-masked]>
Date: Tue, 14 Apr 2026 18:52:06 -0400

On Tue, Apr 14, 2026 at 06:03:47PM -0400, Jeff King wrote:

> > -perl -MHTTP::Date -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
> > -perl -MTime::ParseDate -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
> > +test_lazy_prereq DATE_PARSER '
> > +	perl -MHTTP::Date -e 0 ||
> > +	perl -MTime::ParseDate -e 0
> > +'
> 
> Maybe I am being dense, but I don't see how the original would have
> problems with "set -e". The perl command is on the left-hand side of an
> &&, so "set -e" will be suppressed.

Joy of joys, it looks like a bash bug. Using "command" re-enables "set
-e", even on the left-hand side of an &&.

With bash 5.3.9 on my Debian system:

  $ bash -ec 'command false && echo one; echo two'
  two

On bash 3.2.57, tmate'd into the GitHub Actions macOS image:

  $ bash -ec 'command false && echo one; echo two'
  [no output, we exited after command failed]

It triggers in this case because perl in our test suite is a shell
function which runs "command $PERL_PATH".

But I don't think switching to an if/then conditional helps. Doing:

  bash -ec 'if command false; then echo one; fi; echo two'

likewise exits early (but prints "two" on modern versions).

Sadly I do not think we'll see a fixed version anytime soon. Apple is
sticking with ancient bash because of licensing, IIRC. I don't know if
they're backporting any fixes (and even if they wanted to, there are
probably license complications).

Short of requiring a third-party shell, the only workaround I can think
of is to manually "set +e" before using "command", and then restore it
with "set -e". Gross.

-Peff