AFAICT, neither GNU Bash, nor any other relevant package (e.g. GNU coreutils) that is commonly available in GNU/Linux distros, has a ready-made way to define an environment variable such that the attempt will fail, and indicate failure, if the environment variable already exists. Essentially, a "no-clobber" option for variable assignment, with a non-zero exit status on failure.
Shell parameter expansion (aka "parameter substitution") approaches avoid clobbering, but do not report failure:
unset MY_VARIABLE
: ${MY_VARIABLE:='my_value'}
: ${MY_VARIABLE:='this_will_fail_but_will_nevertheless_have_exit_code_0'}
echo $?
0
echo $MY_VARIABLE
my_value
The best workaround I have come up with is to create a function ("safedef") for that purpose:
die() {
echo -e >&2 "$@"
exit 1
}
safedef() {
if [ -v $1 ]; then
die 'Name conflict. Variable already defined. Will not overwrite it.'
else
# Create and assign environment variable
export $1="${*:2}"
fi
}
safedef MY_VARIABLE 'my_value'
safedef MY_OTHER_VARIABLE 'my_other_value'
# Etc, etc...
Questions:
- Have I overlooked a ready-made way to achieve this, provided by a free software package that is available in some or all mainstream GNU/Linux distros?
- Have I overlooked some kind of bug in
safedefthat means it could well unexpectedly fail to work as intended? (If so, what is the bug, and what might be a better approach?)
readonly?safedefapproach above); and 2. because if the existing variable was defined by some other process, and that process needs to be able to overwrite it, then my marking it as read-only might cause that other process to fail (and indeed to do so in a subtle and headache-inducing manner).safedefachieves it and can't readily be bettered. However, ... "Or any variable scalar or not (array, hash...), exported or not?" ... it would certainly be nice to have a general solution :)