Bash – make bash exit if declare statement fails

bashbash-expansion

tl;dr I want bash to automatically exit after declare var=$(false).

My bash scripts use set -e (or set errexit). However, when using declare variable declaration idiom, the declare appears to "block" returning the return code from a shell substitution.

$ var=$(false)
$ echo $?
1

$ declare var=$(false)
$ echo $?
0

Therefore, bash will not exit due to the error. I know I could test var but that is too cumbersome after every declare statement.

How to automatically exit bash after a failure during declare?

Edit: To clarify, I am looking for an Answer that 1) works for possibly locally scoped variables, and 2) works for possibly readonly variables, and 3) requires only one statement.

Best Answer

Using set -e will not work as intended with the code you have. The reason being for the errexit to trigger the command has to return a non-zero exit code, but with

declare var=$(false)

though the assignment of false and the result of the $(..) causes a non-zero exit code, using declare obfuscates this error code and since the command by itself ran without any problem assigning a value to variable var, the delcare built-in sets the exit code to 0 which causes your error trap not to fire.

One way to solve the problem would be to separate the declare initialization and the value assignment

#!/usr/bin/env bash

set -e
declare var
var=$(false)

Not only declare other built-ins like export andlocal also obscure the exit code when used in cases like above. See a case of using local in a function

set -e
f() { local var=$(false); }
f 

As with the above case of declare, here in the function local obscures the exit code set from $(..). You need to separate the initialization and assignment to var to make it working.

BashFAQ/105 - Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected? explains in detail about the pitfalls of using set -e and also the recommended error handling mechanisms.

Related Question