Eric Sunshine [off-list ref] writes:
The --chain-lint option detects broken &&-chains by forcing the test to
exit early (as the very first step) with a sentinel value. If that
sentinel is the test's overall exit code, then the &&-chain is intact;
if not, then the chain is broken. Unfortunately, this detection does not
extend to &&-chains within subshells even when the subshell itself is
properly linked into the outer &&-chain.
Address this shortcoming by eliminating the subshell during the
"linting" phase and incorporating its body directly into the surrounding
&&-chain. To keep this transformation cheap, no attempt is made at
properly parsing shell code. Instead, the manipulations are purely
textual. For example:
statement1 &&
(
statement2 &&
statement3
) &&
statement4
is transformed to:
statement1 &&
statement2 &&
statement3 &&
statement4
so, with --chain-lint, we would transform this
mkdir -p a/b/c &&
(
cd a/b/c
rm -fr ../../*
) &&
statement 4
into this sequence
(exit $sentinel) &&
mkdir -p a/b/c &&
cd a/b/c
rm -fr ../../* &&
statement 4
and then rely on the non-zero exit to cancel all the remainder?
We didn't create nor cd to the t/trash$num/a/b/c thanks to the &&
chain, and end up running rm -fr ../../* from inside t/trash$num?
Hmmmmm....