zsh: The last shell you’ll ever need!

Introduction

Last week, the all-knowing Mako inspired me to give zsh a shot. He started me off with a .zshrc file, and now a week later, I’ve been spreading the word to as many people as I can. But let’s rewind a bit.

First off, the basics: I expect most of you to be familiar with what a shell is. A command-line shell is a user interface to the operating system. For all practical purposes, you know it as “the thing that you type commands into”. There are many, many shells to choose from, and most *nix’es come with different default shells too. Arguably, the most popular shell in use today is the GNU Bourne Again Shell, better known as bash. The other main family of shells is known as the C shells (csh, tcsh) — named after their C-like scripting syntax.

So what’s zsh and why would I want it over my current shell?

The shell I am raving about today is the Z-shell, or zsh. Zsh is an expansion on the Korn shell (ksh), which is an expansion on bash. (UPDATE: The previous statement, as pointed out by a lot of readers, is incorrect. ksh existed before bash, and if anything bash was inspired by ksh. I was merely going by the feature lists and noticing that modern ksh is a lot more capable than bash, and thereby assuming this relationship. I will leave the statement there because changing it might “look bad”).  It is one of the most full-featured shells you can ask for, and I would go as far as to say that everyone has something to gain from using zsh. Particularly if you have stuck with bash or your operating system’s default shell, I strongly recommend you give zsh a shot! What do I like about it?

  1. Acts extremely similar to bash. You can use zsh exactly the way you use bash and not learn a single thing, and even then it’s an improvement! Compatibility with familiar shells is very important. Switching from bash to zsh is not going to be like switching from GEdit to vim. You’ll be instantly at home in that all your bash shortcuts/commands will work as expected, but you’ll also have access to zsh’s goodies. If you’re a shell scripting addict, you’ll be pleased to know that zsh’s scripting syntax is mostly backwards-compatible with bash, too.
  2. Typo correction. How many times have you typed something like aptg-et or other mangled commands? Well, if I do that in zsh, I get a message asking: “zsh: correct 'aptg-et' to 'apt-get' [nyae]? “. Magical, isn’t it? This autocorrect also applies to any parameters or paths or filenames you type.
  3. Phenomenally intelligent tab completion. Wait… I hear what you’re saying already. “Duh you idiot, bash does this too! You just need to uncomment/install bash-completion.” No, that’s not what I mean. Can your bash:
    1. Present suggestions in a menu that you can browse by arrow keys?
    2. Complete the kill command by showing a menu of all your processes?
    3. Complete the aptitude or ls commands by showing a menu of relevant parameters and a short description of what they do?
    4. In addition to exact matches, show also near matches in a separate section?
    5. Pop up completion options even for complex commands virtually instanteously, without bash’s dreaded “UH OH I should’ve typed a few more letters first!” delay?

    If you could say yes to any of these questions, then please let me know! Because after 3 years of using bash, my bash sure doesn’t!

  4. Share history across sessions. Multiple simultaneously running zsh sessions can share history with each other, rather than clobbering each other up. One of the most frustrating things to a bash user is typing in a long command, then searching for it again the next day via Ctrl+r, only to find it nowhere in the history.
  5. Built in pager. I’m a lazy person. And I think you are, too. zsh comes with a pager directly in the shell. This means you can type things like <README and it is equivalent to less README or cat README | less
  6. More powerful globbing. Globbing is the fancy term for “wildcards on steroids” — your matching expressions like “*.c” or “*Office*S03E[0-2][0-9]*.avi” and so on. As the zsh introduction shows, zsh gives you way more powerful globbing expressions. You’ll rarely find yourself forced to whip out the find command or a GUI search tool.
  7. More bearable scripting language. If you’re not a shell scripter, you probably will have no idea what I’m talking, but all you shell scripters out there: Say goodbye to all those bash gotchas. How many times have you been bitten by a statement like [ $FOO = $BAR ] erroring out because FOO or BAR were empty, and then having to resort to silly tricks like [ x$FOO = x$BAR ] . Well, zsh has rescued you with its double-bracked comparisons. [[ $FOO = $BAR ]] will always work, and [[ $FOO && $BAR ]] comes a lot more naturally than [ $FOO -a $BAR ]. I can’t even begin to scratch the surface of zsh’s programming capabilities, but I encourage you to give it a shot!
  8. A lot more. Remember, I’m a beginner too. I have just hit the tip of the iceberg myself. Consult zsh’s wonderful documentation (which I will link to later) for everything you want to know about zsh.

Ok, You Convinced Me. How Do I Start Using zsh?

Excellent! Glad you decided to give it a chance. Unfortunately, zsh won’t do everything I just raved about when you install it. In fact, by default it’s quite bland. I recall two years ago, I heard some buzz about zsh, so I installed it and fired it up, and thought to my self “WTF is this crappy thing? It doesn’t even have tab completion! I’m going back to bash.” To get zsh to do magical things, you need to configure it by a file called .zshrc. This is the analog of bash’s .bashrc or csh’s .cshrc (which is, by the way, not a city in Bosnia). The way most people begin populating this file is by googling for zshrc and using someone else’s as an example. Well, I’ve got some of my own zshrc files too, which I based off Mako’s and various googled zshrc files, so I do not in any way claim any credit to these creations. So, let’s get started:

  1. Install zsh from your distribution. You should consult your distribution’s package manager (yum, apt-get, Synaptic, Portage, fink, you know the drill) because they most likely have it packaged. There are generally two packages, a zsh and a zsh-devel or zsh-beta package. The beta package is newer and contains new features and enhancements, but may have bugs. I personally use the betas and have yet to have a problem, but this choice is up to you. Both work great.
  2. Grab a zshrc file. You can either google-and-build one you like, or start from my sample ones:
    1. Linux:This is the standard one I use on my Linux machines. I run Ubuntu but I didn’t put anything distro-specific in there.
    2. Mac OS X: This is almost identical to the Linux one, except it fixes the behavior of the delete/pgup/pgdn/home/end keys and has a prompt color scheme for black text on white background display schemes (because personally I find that looks better on my Macbook)

    This file should be saved at ~/.zshrc; that is, a file called “.zshrc” in your home directory.

  3. Enjoy, read documentations, tweak to your heart’s content! Please, go to zsh’s homepage and look around the documentation for more tips and tricks. I’m a newbie to zsh — I can’t teach you much about it because I’m learning as we speak.

Additional Resources

If you like what you see but this has left you with more questions than you started with, please seek out these wonderful documentation resources:

  • zsh Homepage. Here you can find links to a lot of good resources.
  • zsh Introduction. A really quick read to give you a good overview of zsh’s abilities.
  • zsh Guide. This is a longer guide but geared towards comprehensively addressing zsh from the user’s standpoint.
  • zsh Manual. This is a really long manual that covers everything you’d want to know about zsh, particularly if you’re a scripter you’ll like this one!
  • zsh Cheatsheet. For the lazy and impatient! (though it’s upside down… sorry, not my fault!)
  • zsh FAQ. Great for those whiny questions that go like “Waah, why does zsh do X and Y differently from my old shell?”
  • zsh Wiki. Community-contributed and maintained documentation, tips/tricks, zshrc’s, extensions and addons.

P.S. Avoid the temptation to spend your next week locked in your room playing with zshrc. It’s really not healthy… (By the way, should hostname be colored $PR_BLUE or $PR_GREEN in the prompt? I’m still contemplating that in my zshrc!)

51 Comments »

  1. Travis said

    Excellent rundown. I admit I’ve only tried it for a few minutes and never bothered to really dig into it. I’ll have to check it out!

  2. Cower said

    Good article, covers zsh fairly well I guess. I appreciate the Linux zshrc, since mine was messy and not very useful. Also, may wish to delete the spam comment by anson.

  3. Matt said

    root@shambler:/var/www/htdocs# zsh
    \u@\h:\w\$ lol
    zsh: command not found: lol
    \u@\h:\w\$

  4. infinitycircuit said

    Bash also has the [[ ]] test keyword in version 3 and later versions of 2.

  5. Jamie said

    I used zsh for almost a year before I discovered Fish (http://fishshell.org/). It gets me everything I want except the uber-auto-completion, which I only really miss for super-compact directories (for example, tail /v/l/m expanding to tail /var/log/mail.log).

    It’s a bit different from bash syntax, but it has what winds up being a much more powerful scripting language. It handles multiple shells sharing environment, not just history. File globs are just as powerful as zsh.

    And the best part? I don’t need a config file. Fish is absurdly usable right out of the package manager. If I want to set up aliases or custom functions though, it’s just a matter of defining them (interactively) and telling fish you’d like to store them – they wind up in ~/.config/fish/functions.

    Just be aware that you’ll spend more time switching from bash to fish than you would from bash to zsh if you were a power shell user.

  6. […] for Linux and Mac that allow you to instantly take advantage of zsh’s user-friendly power.read more | digg […]

  7. TrashCat said

    Bash has been able to do [[ $FOO == $BAR ]] since about 1998. I’m not quite sure why you say it can’t.

    I’ve never had to use the “x$variable” gotcha in any of the scripts I have ever written. I even tried your example on one of our old servers that has bash 2.05 (from ~2001) and it worked fine.

  8. Jim said

    ksh is an expansion on bash? That’s not how I remember it. I remember stumbling across a ksh binary for SunOS 4.1.3 way back when (ca. 1995) and that was my intro to ksh.

    I don’t recall when I first discovered bash, but it was quite some time after discovering ksh. And once I discovered bash, there was no turning back. Nowadays, the only purpose I can see for having ksh around is because Oracle DBAs seem rather fond of it. 😉

    As for zsh, I may check it out, although in my environment (ie, working on client systems), I can find bash on Solaris and Linux boxen (don’t recall regarding HP-UX), but AIX doesn’t seem to, at least not by default. So the benefits would be limited to systems which already have zsh involved; if it’s not installed there, I don’t have the latitude to go around installing it, much less to post the request to have it installed just for me. So for me, maybe some limited home use. As it is, I’m still trying to find excuses to develop my Python skills (such as they are).

  9. zsh: The last shell you’ll ever need! « Fried CPU

    Convincing article to switch to zsh. Nice article, very informative. I might give this a shot.

  10. […] Link to Introduction to zsh, a powerful and smart Linux/Unix shell […]

  11. uhh, unicode support yet? it didn’t have that last I checked despite all the bells and whistles.

  12. […] shell configuration for OS X, based almost entirely on a post at Fried CPU . All i changed was the ls and ll aliases because Fried’s didn’t work for me. To use […]

  13. My bash (in Ubuntu Feisty) can also do almost everything in your 5 bullet list. For example, completing kill with current processes, completing every command line tool’s parameter (by parsing its –help output I suppose). It can even complete the java command with valid classnames by introspecting the classpath (dunno how it’s doing it, but it is extremely handy for a java programmer like me). I think bash is very flexible in this regard because completion can be extended with additional hooks.

  14. Corsair said

    Agreed, and perfect multi-line prompt support 🙂

  15. Lorenzo E. Danielsson said

    I agree fully. There are two programs that *must* work on my systems at all times: zsh and vi. Those two account for just about 95% of my computer time (and the make utility accounts for most of the remaining 5%).

    I have been using zsh for the last six or seven years. Initially I wanted to try it out because I had heard that it was ksh compatible. Now I don’t use anything else.

  16. Gauss said

    Please don’t knock Bash until you learn everything it has, your article comes off as somewhat uninformed.

    1. Yup I consider this a feature not a bug, but you do too, so I’ll agree and move on 🙂

    2. Bash has typo correction for directories in the cd command. It doesn’t work on commands, but I would also argue that guessing commands could lead to some bad mistakes. Even though it asks it’s very easy to hit ‘y’ and run the wrong command before you realize what you’re doing.

    3.1. Nope, but I don’t use arrow keys all that much.
    3.2. This can be configured if you take a look at the bash man page, auto-completion you can have all sorts of auto-completions, makefile targets, files, processes to the kill command, anything you like
    3.3. Can be setup to do this too. Do a google on bash argument completion people already have this setup. I think that this can be enabled on my most systems just by including the correct file
    3.4. Fair enough, this isn’t in bash, but the auto completion is very very configurable this may be possible
    3.5 I don’t notice much if any delay personally. I did notice a insignificant delay in loading up zsh’s completion module though.

    4. Bash doesn’t do this, in bash the history file is resaved on ever close. That said, I am willing to bet zsh’s method would find ways of not doing exactly as
    I wanted either, but it does sound interesting.

    5. Admittedly cool but only minimally better than bash (alias p=less can do the same with one more keystroke)

    6. Not “way” more powerful, there are a few more extensions to the globbing language, but 99.9% of the globs you ever write can be done in either shell.

    7. Shell scripts are shell scripts. Mostly you’ll want to stick with posix shells and posix commands so that if zsh doesn’t exist you can run them on any system. As someone else said Bash does support at least the functions you tout for zsh. The x$FOO = x$BAR is a posix compliance hack, not a Bash hack, and the double brackets are supported. Any serious programming should be done with a more robust language (python/per/ruby).

    8. You should really check out Bash, it’s installed on nearly every system by default, has pretty much the same features. While zsh has some improvements, they don’t offer enough to make me want to port all my .bashrc stuff to zsh (assuming it’s even installed on every computer I have to use).

  17. n0vus said

    Wow, holy crap zsh is pretty amazing. I’m never going back to bash :P.

  18. tim said

    For multiple Bash sessions not obliterating your command history, use this:
    shopt -s histappend

    Also history-related, if you repeat commands but don’t want the duplicates to clutter your history,
    export HISTCONTROL=ignoredups

  19. Marius Piedallu van Wyk said

    More features:

    1) ls -1 /**/*(s)

    will match all the setuid files on your filesystem… the glob ** matches any and all paths (use with caution) and the (s) is one of the many ‘Glob Qualifiers’

    2)
    ~> test=/usr/local/lib/test
    ~> cd ~test/
    ~test>

    To mention only two that I saw missing. I’ve been using bash and zsh for some time to great depth (I currently use bash since it default) but still prefer zsh. Bash *IS* able to do many of the things zsh can do… but with great difficulty. Just see the difference in making my pointer in ZSH manipulate my kterm prompt, tabs and window title using the precmd() function, ex:

    precmd () {
    echo -n “33]2;$PWD> – $USERNAME@$HOST ($status)”
    }

  20. Neil said

    Other then a little fine tuning I had to do on PS1 (sorry, I had to tone down the colors), your zshrc is great.

    And after only playing with zsh for maybe ten minutes, I can tell you that I will NEVER look back at bash again.

    Great article!

  21. Asa said

    Dude, I’ve been using bash for nearly 10 years now and always been too lazy to try to learn another shell. I just installed zsh and its totally lush. Don’t think I” bother with bash any more!

    You totally sold me on the smart tab completion. I use Debian and remember thinking for ages that I wished I could just type “apt-g” “i” instead of “apt-get install every time. AND NOW I CAN!!

    Nice one.

  22. Jan said

    Thanks, I used it for some time on a rescue disk, until I ran into some weird error (dont know what it was anymore), which was totally unclear to me. After switching to another shell, the command worked. After this I never touched the very very great shell again, as I do not want to get errors meaning “change your shell” but saying something else. This is just a word of warning in case someone runs into problems, try another shell, otherwise zsh ist great!

  23. […] Full Article Here […]

  24. adamo said

    ksh is an expansion of the Bourne Shell (/bin/sh) and not of the Bourne Again Shell (/bin/bash).

  25. Just a bit of historical correction: KSH definitely is NOT an expansion on BASH; rather it is an expansion on the System V Bourne Shell, /bin/sh.

    So is BASH, but as far as I recall KSH predates BASH.

    ZSH was an attempt to provide some of the same features as KSH (and then some) at a time when KSH source was not legally available outside the AT&T System V environment.

  26. Andrea said

    Vi(m) and Emacs keybindings, for example, i love the Ctrl-/ (undo)…

  27. liquidat said

    Interesting – however, there is one thing which holds me back from adopting zsh at the moment:
    With your .zshrc the tab completion is not working as I would expect it. Imagine having two directories, Downloads and Documents. Now I want to cd into Downloads: I hit “cd Do” and press tab. I’m offered with the nice tab completion interface, move over to the Downloads entry (with the arrow keys for example) and press enter. I would expect now that “Downloads” is chosen and that the “cd ” command is executed – but that doesn’t happen. I have to press enter a second time. And that is such an unbelievable waste of time.

    How can I correct it? Or where is the best place to ask such a question?

  28. Bryan said

    That’s behavior as normal, imagine a totally separate scenario where you have two things in one line you want tab complete, your way you just can’t do it because it automatically commits the line after one tab complete. Possibly the chances of you needing two or more are low, but if you do and you change it to this form… You’re totally fucked.

  29. liquidat said

    Bryan: I don’t see your point: if I would like to have two thinks I would first use the tab completion without pressing enter, than press one or two buttons of the next part I need and would again use the tab completion. There is simply no need to use enter as far as I see.

    Please tell me an example to show me where you need enter without executing the command. And please tell me how you deal with the tab completion otherwise, because I seriously doubt that anyone out there uses two enters to execute a command!

  30. jdong said

    We all use two enters to execute a command…

    For example: cd /usr/local && ls -alh lib/ > /tmp/locallib.txt

  31. libdave said

    1st thing I needed to know using zsh: how to invoke vi editing

    in bash:
    set -o vi

    in zsh
    bindkey -v

    Also what I like: when editing history it allows editing compound statements without flattening it (as is done in bash).

  32. liquidat said

    Before I now dive deeper into the discussion about the pros and cons: I just wanted to know how to change this in the first place – nothing else!

    So if anyone is interested, I figured out that tab completion works like *I* would expect it if I take the here proposed zshrc and comment out this line:
    zstyle ':completion:*' menu select=1 _complete _ignored _approximate

  33. jdong said

    Awesome for you — that’s the beauty of zsh’s customizability 🙂

  34. […] short howto explains how to figure out which key binding is connected with which key. I just read a post about zsh and once again was curious about the possibilities and the advantages of that shell. The author […]

  35. too said

    $ rm foo *

    zsh: sure you want to delete all the files in /home/user [yn]?

  36. Still no unicode support. It’s 2007. I used zsh until I couldn’t display Cyrillic and had weird errors when working with UTF-8 characters.

    I did some research, and still, to this -day- they haven’t added Unicode support:
    http://www.zsh.org/mla/workers/2005/msg00762.html

    If I had time (hah) I’d do it. Please, someone step up to the plate! The devs themselves are stuck. This is the Achiles heel of zsh!

  37. I take that back, looks like it’s getting there:

    2007-04-19 : Release 4.3.4
    This now contains most of the planned support for multibyte characters. There are still some problems notably with Unicode combining characters and composition of characters (notably on MacOS).

    I can finally come back!

  38. jdong said

    Hey buddy, I think we’re in year 2007 now. 🙂

    Basic Unicode stuff works fine here…

  39. […] Zsh overview Filed under: OSX, Linux — 0ddn1x @ 2007-07-30 23:33:13 +0000 https://friedcpu.wordpress.com/2007/07/24/zsh-the-last-shell-youll-ever-need/ […]

  40. Keith said

    I have known about zsh for a long time, but hadn’t really tried it out myself. Perhaps, I will do so tonight, when I switched into my linux system. If that’s really true that zsh is really renowned for what you’ve said.

  41. […] Top 10 GMail Tweaks Are ISPs modifying your web pages? 12 Ways to Use Facebook Professionally Introduction to zsh, a powerful and smart Linux/Unix shell 50+ Tools For Torrenting Hands-On With The OpenMoko Phone Intel cuts prices on quad-core chips […]

  42. […] For a good rundown, check this dude’s blog article. […]

  43. […] zsh: The Last Shell You’ll Ever Need. A more gentler introduction to zsh and the tale of why one bash user switched to it. […]

  44. […] read more | digg story […]

  45. […] read more | digg story […]

  46. […] read more | digg story […]

  47. […] read more | digg story […]

  48. […] read more | digg story […]

  49. thanks for the GREAT post! Very useful…

  50. adi said

    Nice article. I am a bash user and wanted to try zsh after listening a lot of good things about it. But I could never find the time to learn all the customizations of zsh and kept going back to bash. With your zshrc I am sticking to zsh.

    Thanks.

  51. Maximus said

    I would like to see a continuation of the topic

RSS feed for comments on this post · TrackBack URI

Leave a reply to Bryan Cancel reply