๐ŸŒ
GitHub
github.com โ€บ agkozak โ€บ zsh-z
GitHub - agkozak/zsh-z: Jump quickly to directories that you have visited "frecently." A native Zsh port of z.sh with added features. ยท GitHub
Zsh-z is a command-line tool that allows you to jump quickly to directories that you have visited frequently or recently -- but most often a combination of the two (a concept known as "frecency"). It works by keeping track of when you go to ...
Starred by 2.4K users
Forked by 79 users
Languages ย  Shell
๐ŸŒ
IBM
ibm.com โ€บ docs โ€บ en โ€บ zos โ€บ 3.1.0
zsh - The Z shell
Get assistance for the IBM products, services and software you own ยท Provides fixes and updates for your system's software, hardware, and operating system
The Z shell (Zsh) is a shell and a command-line interpreter for shell scripts. Zsh mostly maintains the Bourne shell's syntax and behavior, but in its default configuration deviates in some significant โ€ฆ Wikipedia
Factsheet
Original author Paul Falstad
Developers Peter Stephenson, et al.
Release 1990; 36 years ago (1990)
Factsheet
Original author Paul Falstad
Developers Peter Stephenson, et al.
Release 1990; 36 years ago (1990)
๐ŸŒ
Wikipedia
en.wikipedia.org โ€บ wiki โ€บ Z_shell
Z shell - Wikipedia
3 weeks ago - In 2020, Kali Linux adopted Zsh as the default shell since its 2020.4 release. ... Programmable command-line completion that can help the user type both options and arguments for most used commands, with out-of-the-box support for several hundred commands ยท Sharing of command history among all running shells ยท Extended file globbing allows file specification without needing to run an external program such as find ยท Improved variable/array handling (non-zero...
๐ŸŒ
Reddit
reddit.com โ€บ r/zsh โ€บ introducing zsh-z
r/zsh on Reddit: Introducing ZSH-z
December 13, 2018 -

I've used z.sh both in bash and in ZSH for years now to jump quickly from directory to directory. That script relies heavily on awk, and it struck me that the same job could be done in ZSH without awk -- or date, sort, or sed, for that matter.

I'd like to introduce ZSH-z, a native ZSH port of z.sh. It's quite a bit faster than its original, as it avoids unnecessary subshells, and the only external commands it still uses are mv and rm. The speed increase can be felt particularly on Windows (MSYS2/Cygwin/WSL), which has problems with forking.

I've also introduced little fixes, and one new feature which is now on by default: completion menus are populated according to how often you go to directories and how recently you've been to them ("frecency"), whereas in the original the menu is simply sorted alphabetically. The original behavior is still there if you set ZSHZ_COMPLETION=legacy.

https://github.com/agkozak/zsh-z

๐ŸŒ
Oh My Zsh!
ohmyz.sh
Oh My Zsh - a delightful & open source framework for Zsh
Oh My Zsh is a popular open-source Zsh configuration framework loved by developers worldwide. It includes 300+ plugins, themes, and tweaks to supercharge your terminal experience.
๐ŸŒ
Medevel
medevel.com โ€บ zsh-z-app
Zsh-z: Quickly Jump to Your Most Frequent Directory (Linux and macOS) - Supercharge Your Terminal
September 26, 2025 - If you live in the terminal, as most developers do, navigating deep directory trees with cd can quickly become tedious. Enter Zsh-z, a blazing-fast, intelligent directory jumper that learns your habits and gets you where you need to go with just a few keystrokes. What Is Zsh-z? Zsh-z is a
๐ŸŒ
ZSH
zsh.sourceforge.io
ZSH - THE Z SHELL
Zsh is a shell designed for interactive use, although it is also a powerful scripting language. Many of the useful features of bash, ksh, and tcsh were incorporated into zsh; many original features were added. The introductory document details some of the unique features of zsh.
Find elsewhere
๐ŸŒ
Yurik
yurik.info โ€บ blog โ€บ zsh-z-tool
zsh-z: The Directory Jumping Tool I Can't Live Without | Yuri's Dev Blog
October 17, 2025 - Meet zsh-z - a smart directory jumping tool I've relied on for years and genuinely can't work without.
๐ŸŒ
GitHub
github.com โ€บ rupa โ€บ z
GitHub - rupa/z: z - jump around ยท GitHub
If it is not set, symbolic links will be resolved when added to the datafile. In bash, z appends a command to the PROMPT_COMMAND environment variable to maintain its database. In zsh, z appends a function _z_precmd to the precmd_functions array.
Starred by 17K users
Forked by 1.2K users
Languages ย  Shell 64.6% | Roff 35.0% | Makefile 0.4%
๐ŸŒ
ZSH
zsh.sourceforge.io โ€บ Doc โ€บ Release โ€บ index.html
The Z Shell Manual (zsh)
This Info file documents Zsh, a freely available UNIX command interpreter (shell), which of the standard shells most closely resembles the Korn shell (ksh), although it is not completely compatible.
๐ŸŒ
Smashing Magazine
smashingmagazine.com โ€บ 2015 โ€บ 07 โ€บ become-command-line-power-user-oh-my-zsh-z
Become A Command-Line Power User With Oh My ZSH And Z โ€” Smashing Magazine
July 11, 2015 - While this works for most, some users have trouble getting this to work. If that is the case, download download Z and put it in your home directory so that itโ€™s located at ~/z.sh. Then, in your .zshrc file, include the following and then source your .zshrc file again.
Top answer
1 of 3
5

${var+string} is the same operator as in the Bourne shell (from the late 70s) and in any POSIX shell (including bash). You can find it described in the zsh documentation in info zsh 'Parameter Expansion':

${NAME+WORD}
${NAME:+WORD}
If NAME is set, or in the second form is non-null, then substitute WORD; otherwise substitute nothing.

It's harder to find in info bash 'Parameter Expansion' but it's the same there. For sh, you can check the POSIX specification (though like in the bash manual, you need to pay attention to the sentence that mentions the effect of omitting the colon in ${parameter:+word}ยน).

The main difference with bash and other Bourne-like shells, is that that ${ZSH_MOTD_CUSTOM+x} being unquoted is not subject to split+glob, because in zsh, when you do want IFS-splitting and/or globbing performed upon parameter expansion you have to request it explicitly ($=var for splitting, $~var for globbing (strictly speaking for the contents of $var to be treated as a pattern), $=~var for both, which be the equivalent of $var in other shells).

It's wrong though as unquoted expansions are still subject to empty removal. In that case though, by accident, it's not going to be a problem, and may be why the author chose to write it [ ! -z $expansion ] instead of [ -n $expansion ] which wouldn't work.

If $expansion is empty (in the case of ${ZSH_MOTD_CUSTOM+x} if $ZSH_MOTD_CUSTOM is not set), [ ! -z $expansion ] becomes [ ! -z ] instead of [ ! -z '' ], so it doesn't test whether the expansion is non empty, but whether -z itself is an empty string (which it isn't obviously), so it achieves the right outcome (test whether the variable is set) for the wrong reason.

In bash, that unquoted ${ZSH_MOTD_CUSTOM+x} would have been subject to split+glob so that would be even more wrong, but because it can only expand to either the empty string or a literal x, the problem would have been only if $IFS happened to contain x:

$ bash -xc 'IFS=y; [ ! -z ${HOME+x} ]; echo "$?"'
+ IFS=y
+ '[' '!' -z x ']'
+ echo 0
0
$ bash -xc 'IFS=x; [ ! -z ${HOME+x} ]; echo "$?"'
+ IFS=x
+ '[' '!' -z '' ']'
+ echo 1
1
$ zsh -xc 'IFS=x; [ ! -z ${HOME+x} ]; echo "$?"'
+zsh:1> IFS=x
+zsh:1> [ ! -z x ']'
+zsh:1> echo 0
0

The correct syntax in any POSIX shell would be:

if [ -n "${ZSH_MOTD_CUSTOM+x}" ]

Even works here in the Bourne shell where [ -n "$var" ] fails for values of $var that are things like =, -gt... as the expansion can only be x or the empty string (so not any of the problematic ones in those ancient implementations of [).

Now zsh has more idiomatic ways to check whether a variable is set such as:

if (( $+ZSH_MOTD_CUSTOM ))

Where $+var expands to 1 if $var is set and 0 otherwise.

Or:

if [[ -v ZSH_MOTD_CUSTOM ]]

ร€ la ksh (also found in bash).

In any case, [ ! -z "$ZSH_MOTD_CUSTOM" ], itself a convoluted way to write [ -n "$ZSH_MOTD_CUSTOM" ] does something different: if checks whether the variable is non-empty or not regardless of whether it is set or not. The main difference is that it will return false if $ZSH_MOTD_CUSTOM is set, but to an empty value. Contrary to the ${ZSH_MOTD_CUSTOM+x} variant, it would also cause an error if the variable was unset and the nounset option was enabled.

$ zsh -c 'if [ -n "$foo" ]; then echo non-empty; else echo empty; fi'
empty
$ foo= zsh -o nounset -c 'if [ -n "$foo" ]; then echo non-empty; else echo empty; fi'
empty
$ foo= zsh -o nounset -c 'if [ -n "${foo+x}" ]; then echo set; else echo unset; fi'
set
$ zsh -o nounset -c 'if [ -n "$foo" ]; then echo non-empty; else echo empty; fi'
zsh:1: foo: parameter not set
$ zsh -o nounset -c 'if [ -n "${foo+x}" ]; then echo set; else echo unset; fi'
unset
$ zsh -o nounset -c 'if [ -n "${foo-}" ]; then echo non-empty; else echo empty; fi'
empty

(in the last one, we use ${foo-} which expands to the same thing as $foo but avoids the effect of nounset (aka set -u)).


ยน Note that in the Bourne shell where the feature comes from, initially (in Unix 7th edition from the late 70s) only the versions without colon were supported, the ones with colons came later in SysIII.

2 of 3
3

This is a parameter (variable) expansion syntax that's also found in Bash. Probably in most other Bourne-style shells, too. The only thing special to zsh in your example is the variable being tested.

In the bash man page we see two things. The explanation of this expansion syntax:

  ${parameter:+word}
    Use Alternate Value. If parameter is null or unset, nothing is substituted,
    otherwise the expansion of word is substituted.

And a few paragraphs earlier, at the top of the section of expansion syntax, there is something a lot of people overlook:

  When not performing substring expansion, using the forms documented below
  (e.g., :-),  bash  tests for a parameter that is unset or null.  Omitting
  the colon results in a test only for a parameter that is unset.

That last sentence is the relevant part: Omitting the colon results in a test only for a parameter that is unset. To illustrate, the syntax as given in the man page is:

  ${parameter:+word}

with the colon omitted it is:

  ${parameter+word}

And the difference is that the latter syntax returns the value in word in all cases except when the variable is unset (doesn't exist). So the syntax you saw in your zsh script:

  ${ZSH_MOTD_CUSTOM+x}

Returns x if $ZSH_MOTD_CUSTOM has been defined (no matter what the value is - even an empty string), but returns an empty string if the variable is not defined.

In the end, your script example tests only that the variable exists, without regard to the value it contains. I answered by quoting the Bash man page because you mentioned you have been a bash user and will find the bash descriptions familiar.

It's not a common idiom in the Bourne-style shell scripts I've seen over my (fairly long) career, so a lot of people aren't aware of the :-, :=, :?, and :+ syntax without the :. I learned about them only recently myself.

๐ŸŒ
Thenybble
thenybble.de โ€บ posts โ€บ stupid zsh tricks
Stupid ZSH tricks | thenybble.de
October 11, 2021 - You need to be using zsh-z. It's like the Firefox address bar for directories. zsh-z maintains a history of your directories, sorted by "frecency", frequency and recency.
๐ŸŒ
Opensource.com
opensource.com โ€บ article โ€บ 19 โ€บ 9 โ€บ getting-started-zsh
Getting started with Zsh | Opensource.com
September 17, 2019 - Z-shell (or Zsh) is an interactive Bourne-like POSIX shell known for its abundance of innovative features.
๐ŸŒ
Z-Shell
wiki.zshell.dev
A Swiss Army Knife for Zsh Unix shell | Z-Shell
See Zi in action โ€” from installation to plugin setup and configuration. The recording shows a full plugin installation workflow โ€” from fetching sources to setting up completions and reports. Turbo mode defers plugin loading until after .zshrc is processed, giving you an instant prompt every ...
๐ŸŒ
Z-Shell
wiki.zshell.dev โ€บ ๐Ÿš€ getting started โ€บ โšก๏ธ installation
โšก๏ธ Installation | Z-Shell
June 15, 2025 - To enable Zi, source the zi.zsh from the previously set up directory placing the following snippet in the .zshrc file:
๐ŸŒ
SitePoint
sitepoint.com โ€บ blog โ€บ computing โ€บ 10 zsh tips & tricks: configuration, customization & usage
10 Zsh Tips & Tricks: Configuration, Customization & Usage โ€” SitePoint
November 15, 2024 - Bonus Tip: if youโ€™re feeling lazy, you can just drag and drop a folder onto the terminal window and the path will be expanded for you. z is a handy plugin that builds a list of your most frequent and recent folders (it calls these โ€œfrecentโ€) ...