zsh: configuring options

2020-08-29

 | 

~3 min read

 | 

509 words

Recently, I came across a really interesting Unix & Linux StackExchange answer from Stéphane Chazelas on the differences between how shells interpret different glob patterns. THe search was motivated by unexpected behavior I was seeing when trying to use wildcards.

Stéphane’s answer led me to the Zsh Documentation on Options. Specifically, the GLOB_STAR_SHORT:

When this option is set and the default zsh-style globbing is in effect, the pattern '**/*' can be abbreviated to '**' and the pattern '***/*' can be abbreviated to *. Hence `’.c’finds a file ending in .c in any subdirectory, and*.c’does the same while also following symbolic links. A/immediately after theor’***’` forces the pattern to be treated as the unabbreviated form.

The first clause, “when this option is set”, indicated that there was a way to set options / configure zsh. This was not surprising in itself, but it did reveal, that I didn’t know how to take advantage of these options!

Setting Options

Section 16.1 does spell this out. The short answer is:

set <option>
setopt <option>
set -o <option>

These are all equivalent. Also, the option is case insensitive and _ are ignorable (or injectable). So, for the option AUTO_CD, you can do:

% setopt AUTO_CD
% setopt au_tOcd
% set -o autocd

To unset an option there you can prefix with no or use the unsetopt/ set +o:

% setopt NO_AUTO_CD
% unsetopt au_tOcd
% set +o autocd

Reasonable Defaults

Armin Briegel, author of the Scripting OS X blog has a great series on Moving to zsh.

His recommended default options are:

  1. AUTO_CD
  2. NO_CASE_GLOB
  3. CORRECT and CORRECT_ALL

Persisting Changes

Toward the end of his post, Armin suggests:

If in doubt, it may be useful to add this at the beginning of your zsh scripts.

This was part of the mystery. I would set my options in one shell only to have them not set in another shell when I tried (i.e. when I ran setopt I only had the original set).

The answer was to set them in my .zshrc which is where I store all of my zsh config (though there are alternatives).

all users user login shell interactive shell scripts Terminal.app
/etc/zshenv .zshenv
/etc/zprofile .zprofile x x
/etc/zshrc .zshrc x
/etc/zlogin .zlogin x x
/etc/zlogout .zlogout x x

So, instead of:

% setopt NO_CASE_GLOB

which would only set the option temporarily, I made the following tweak:

% echo setopt NO_CASE_GLOB >> ~/.zshrc

And in that way, I saved my newly set configurations to my .zshrc which means they’re loaded in every z shell during boot.


Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!