User:Franklin Yu/Why Zsh

This page is about the reasons why I’m using Zsh as my daily interactive shell.

why switching from Bash to Zsh
Bash is almost the default choice for new CLI users. However, I switched to Zsh because:


 * Zsh has some Fish-like features, such as zsh-syntax-highlighting and zsh-autosuggestions. Tab-completion is also closer to Fish: short description available for options.
 * Zsh has many hook functions. Bash only has  which does the same as   hook in Zsh; other functionality may be simulated with hacks (Bash-preexec is one of the best options).
 * Zsh has anonymous functions; in Bash this can be simulated by defining a function with a long name (hoping that collision doesn't happen), then unset after calling it once.
 * Zsh provides an option . This is very useful when trapping exit of a function, whether the function exits normally or is interrupted. It’s non-trivial to achieve similar effect in Bash.
 * Zsh has built-in support for common functionalities. For example, to join an array variable  with newline character, in Bash you typically play with  ; in Zsh you simply use  . Another example is iterating over an associative array: in Bash you can only iterate over the keys, and access the value with  ; in Zsh you iterate over both keys and values with.
 * The default behavior in Zsh is more intuitive.
 * In Bash, words of unquoted parameters are automatically split on whitespace; this is removed in Zsh. For example, even if variable  contains spaces in it,   is still equivalent to  . As a side effect,   is equivalent to  . (You can even use  ! Bonus point.)
 * In Bash, if variable  is an array, then parameter expansion of   will be the first element. To get all the elements, you need  . (Don’t forget to quote!) For example,   passes the array elements as arguments. In Zsh,   is equivalent to  . In addition,   is intuitive as well: it’s a string.

Reasons people might prefer Bash over Zsh:


 * Zsh does not have a equivalent function as  in Bash.
 * Availability. Bash is ubiquitous. This is critical when working on an environment where Zsh can’t be installed (e.g. without super-user permission being granted). However, on macOS the built-in Bash is very old; many features (like associative array) are only available for Bash 4.0 (or even 4.2).

why not Fish (yet)
Fish is frequently mentioned as another upgrade from Bash. However, some Fish features have been ported to Zsh, such as syntax-highlighting and history-based auto-suggestions. The syntax was claimed to be more suitable for scripting, but associative array is still missing in Fish.

Fish remains a good recommendation for existing Bash users.

possibility of PowerShell
PowerShell is an entirely different beast. On one hand, it is very powerful at scripting:


 * nested hash table
 * package management and centralized package registry
 * manipulate shell environment in C#
 * static type parameters, so function authors get these for free: parameter parsing, parameter validation, basic auto-completion.

But it also lacks quite some functionalities, preventing me from migrating right now:


 * completion library similar to bash-completion and zsh-completions (but it may be more idiomatic to write PowerShell-wrappers?)
 * brief description for completion options?
 * interactive functionalities like auto-suggestions?
 * equivalent of chruby and nvm (maybe we can write our own?)
 * hooks like,  , and   (though they can possibly be emulated with some customized Prompt)
 * subshell (because Windows doesn’t have POSIX fork)

Decision: revisit PowerShell when switching to Windows (for my main machine).

possibility of Nushell
Nushell seems like a new choice. The drawbacks I found so far:
 * not packaged in Debian
 * Lack of completion for many commands (especially corp-internal ones). It can be implemented with ; public ones can be shared on GitHub.
 * no plugin manager like PowerShell
 * no directory stack ( and friends)