2023-08-22 - interesting bash feature

talk is cheap, so i'll show you some code instead:

#!/bin/bash
set -e
false && echo "this never shows up"
echo "result: $?"

what will it show? set -e is there so nothing, right? well – no. it will print this:

 result: 1

…and returns exit code 0. now the open question is: how on earth?! return from the false && whatever is clearly non-zero, yet the next line gets executed! stating that previous line ended with an error.

let's now compare it with almost identical piece of code:

#!/bin/bash
set -e
( false && echo "this never shows up" )
echo "result: $?"

the output? nothing + return code of 1. just as expected!

spoiler alert – it's not a bug. it's a feature. just very non-obvious one. here's a nice explanation. TL;DR version is that set -e exits with an error on non-handled error. eg. this would not fail the script:

if [ 1 -eq 2 ]
then
  echo "wtf?!"
fi

despite [ 1 -eq 2 ] is clearly false. now if we look at foo && bar through the same lenses, here foo's failure is considered “handled”, as there's a post-action && bar, thus $? is set as expected, but script does not stop.

i found this one while inspecting other's person script. it wasn't really clear what's the problem. in the future – when you write a shell script, do use set -e but try keeping 1 statement per line. it makes everyone's lifes easier. :)

thx Wojtek for helping out with this one! :)