63

As a Linux user, I've always just used bash because it was the default on every distro I used. People using other Unix systems such as BSD seem to use other shells far more frequently. In the interests of learning a bit more, I've decided to try out zsh.

As a bash user:

  • What features will I miss?
  • And what ones should I look out for?
3

6 Answers 6

50

For a more extensive answer, read https://apple.stackexchange.com/questions/361870/what-are-the-practical-differences-between-bash-and-zsh/361957#361957

There's already been quite a bit of activity on the topic on other Stack Exchange sites. My experience of switching from bash to zsh, as far as can remember (it was years ago²), is that I didn't miss a single thing. I gained a lot; here are what I think are the simple zsh-specific features that I use most:

  • The zsh feature I most miss when I occasionally use bash is autocd: in zsh, executing a directory means changing to it, provided you turn on the autocd option.⁴

  • Another very useful feature is the fancy globbing. The hieroglyphscharacters are a bit hard to remember but extremely convenient (as in, it's often faster to look them up than to write the equivalent find command). A few of the simpler examples:
        foo*~*.bak = all matches for foo* except those matching *.bak
        foo*(.) = only regular files matching foo*
        foo*(/) = only directories matching foo*
        foo*(-@) = only dangling symbolic links matching foo*
        foo*(om[1,10]) = the 10 most recent files matching foo*
        foo*(Lm+1) = only files of size > 1MB
        dir/**/foo* = foo* in the directory dir and all its subdirectories, recursively⁴

  • For fancy renames, the zmv builtin can be handy. For example, to copy every file to file.bak: zmv -C '(*)(#q.)' '$1.bak'

  • Both bash and zsh have a decent completion system that needs to be turned on explicitly (. /etc/bash_completion or autoload -U compinit; compinit). Zsh's is much more configurable and generally fancier.

If you run zsh without a .zshrc, it starts an interactive menu that lets you choose configuration options. (Some distributions may disable this; in that case, run autoload zsh-newuser-install; zsh-newuser-install.) I recommend enabling the recommended history options, turning on (“new-style”) completion, and turning on the “common shell options” except beep. Later, configure more options as you discover them.

²At the time programmable completion was zsh's killer feature, but bash acquired it soon after.
Features that bash acquired only in version 4 (so were not widely available at the time this answer was posted, and are not available on the system-provided bash on macOS) are in smaller type.

4
  • 6
    Bash 4.0 now supports the autocd feature you discuss above. Enable the feature using the command shopt -s autocd. Then the feature works as you've described. Commented Dec 17, 2012 at 1:28
  • zsh also has the built-in where command, not to be confused with the which command.
    – Sildoreth
    Commented Apr 17, 2015 at 18:14
  • @EdGrimm I think GNU and FreeBSD find can do everything zsh glob qualifiers can do (with -exec of a shell for things like selection with e and a pipeline into tools like sort and sed for rewriting with e and sorting). A lot more verbosely, of course. Commented Apr 11, 2019 at 13:50
  • After checking and rechecking the find manpage for more than a decade, I guess I stopped really looking. But if I'd have checked one last time before commenting, I'd have at least seen the -size option now takes units down to bytes.
    – Ed Grimm
    Commented Apr 12, 2019 at 3:39
12

zsh lets you edit a multi-line command (see zsh line editor), bash doesn't. If you try the same trick (Ctrl-p), bash fetches the last command.

2
  • 3
    Bash does this, at least as of version 4.2.37; it replaces newlines by semicolons and gives you a single line to edit. Commented Jan 24, 2014 at 23:57
  • 2
    Still not as nice. (:
    – SilverWolf
    Commented Jan 23, 2018 at 19:56
12

Also the default tab completion is better than bash... for example...

~/.e.dTAB will expand to ~/.emacs.d/ in zsh, bash will just beep.

3
  • it didn't. what non-default setopt option do you use for that (if any) ?
    – user86041
    Commented May 22, 2018 at 18:44
  • I realized that I have _-. set as a wildcard. zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' . See stackoverflow.com/q/7906078/311660
    – ocodo
    Commented Mar 6, 2019 at 22:29
  • If you can get completion to use fsf , then it can do that! BUt I am finiding the current bash completion very difficult to hook in persoanl replacements for the system installed stuff... Especially for hostname expansion when you have a better methed that 'ssh known hosts' for the host list.
    – anthony
    Commented Oct 9, 2020 at 1:41
10

Bash has the feature of being able to open ports using

/dev/tcp/host/port

or

/dev/udp/host/port

However, it is disabled in Debian as it is seen as a hindrance (if the path actually exists) and outside the scope of what a shell should do. More information [debian mailing list]

1
  • 7
    zsh has the ztcp builtin though which has more capabilities than bash's /dev/tcp, doesn't have /dev/udp. I would rather use socat though. Commented Sep 10, 2012 at 13:43
4

Which - enhanced in zsh

The which command in bash only reveals the location of a command.

In Zsh which will reveal the definition of an alias, the source for a function and the location of a command.

Let's say we had a shell alias:

alias gg='git log'

In Bash if we asked: which gg the result would be void

In Zsh: which gg will give us...

gg: aliased to git log

Let's say we had a shell function:

hello() {
    echo "Hello World"
}

In Bash if we asked: which hello the result would be void.

In Zsh: which hello will give us...

hello() {
    echo "Hello World"
}
2
2

zsh - a complete shell

there are many, reading through zshcontrib(1) one can detect two versions of autoload-able tetris games (the other with ncurses) in zsh in competition with emacs, for completeness (as described).

=

I'd like to mention the = keyword, which can cause irritation with curl (URL's usually have ?var=val in them; but it is unsetopt-able, I think):

  • q file =less (gentoo) resolves to q file $(which less)

= expands to the full path of the command in question.

other goodies

other things, out of the mind, are the right prompt RPS1=%d (to display $PWD in style), Alt + H (run-help ie. man), Alt + ? (which-command), vared, and zed (autoload function), Emacs' minibuffer-like Alt + X to execute widgets without binding them, global and suffix aliases, extended history tracking command completion duration, -m and -regex matchers, shell emulation (eg. csh, ksh with emulate) and autoload run-help with file snippets for the built-ins.

lamentations

I think most, if not all, of the features were implemented a long time ago, and reading through changelogs, there is no major changes and new feature additions, which is very sad (nothing to explore and discover anymore).

bash seem to be more distributed in readline (as opposed to zle) and gnu history in the linux spirit; e.g readline functions and keybindings can be applied globally (as kept in ~/.inputrc and /etc/inputrc) if not overriden by bash-specific bind.

conclusion

I personally think emacs (esp. from the prospect of (the current?) emacs-nox flavor) being the inspiration for the exceptional software like zsh and tmux did a very good job in being an example in such an implementation; for the people appreciating its worth (to the level of not needing/depending on X server). Unix shell is powerful enough, and its continuity and consistency is sufficient for a proper workflow and productivity (in overall computing).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .