Bash export ignores set -ex

bashenvironment-variablesshell

I've run into some strange behaviour today:

#!/bin/bash
set -ex
export a=$(cat foo)
echo "It's a living thing"
b=$(cat foo)
echo "This won't make it"

This won't stop on cat foo even though foo does not exist. But without the export, it fails. Why?

Best Answer

In:

a=$(cmd)

That's a simple command without command part, so the exit status is that of the command substitution instead. In:

a=$(cmd) export a

or

export a="$(cmd)"

There is a command part here (even if in some shells, export is midway between a command and a keyword), so its exit status is returned. If cmd fails and produces no output export a= will still be run and succeed, so export will return a 0 exit status.

Here you'd want:

a=$(cmd)
export a

Or even better, get rid of that unreliable set -e and do proper error handling by hand:

a=$(cmd) || exit
export a

See e.g. BashFAQ 015: "Why doesn't set -e do what I expected?" for further examples of why and how set -e can produce unexpected results.

Related Question