Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zsh: raise error when variable not defined

One nasty aspect with zsh (or with shell scripting in general) is, that if you mistype a variable name, and the resulting name doesn't exist, it is silently treated as empty string, which makes bugs hard to find:

if somecondition
then
  myvar=55
else
  my_var=66
fi
echo $MyVar # Oops

I know that this rule exists for compatibility with good old Bourne shell. I also am aware that I can explicitly catch this error when accessing a variable:

echo ${MyVar?NOT SET}

But if I do this on every variable access, it results in ugly code. Since I have the habit to explicitly initialize all my variables, I'm looking for some way that zsh automatically spills out an error message, when a shell variable or environment variable is accessed, which hasn't been set. Is there a way to do this? I already checked the zshoptions man-page, but didn't found anything suitable.

like image 662
user1934428 Avatar asked Aug 28 '26 12:08

user1934428


2 Answers

In not just zsh but other shells as well, set -u makes references to unset variables an error.

That said, many scripts will not work unmodified when using this option: [[ $foo ]] can no longer be used to check whether foo was provided by the outer environment, requiring [[ ${foo-} ]] instead.

like image 85
Charles Duffy Avatar answered Aug 31 '26 03:08

Charles Duffy


To illuistrate Charles Duffy's answer, and as an example of such a test (in a zsh shell) when nounset is used, you can consider this git commit (for git itself):
See commit 34d8f5a (06 Jun 2016) by Ville Skyttä (scop).
(Merged by Junio C Hamano -- gitster -- in commit 8162401, 06 Jul 2016)

git-prompt.sh: Don't error on null ${ZSH,BASH}_VERSION, $short_sha

When the shell is in "nounset" or "set -u" mode, referencing unset or null variables results in an error.
Protect $ZSH_VERSION and $BASH_VERSION against that, and initialize $short_sha before use.

-   [ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
+   [ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
                       ^
-   [ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
+   [ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
like image 42
VonC Avatar answered Aug 31 '26 03:08

VonC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!