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?
- 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.
- 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.
- 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:
- Present suggestions in a menu that you can browse by arrow keys?
- Complete the
killcommand by showing a menu of all your processes?
- Complete the aptitude or ls commands by showing a menu of relevant parameters and a short description of what they do?
- In addition to exact matches, show also near matches in a separate section?
- 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!
- 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.
- 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
<READMEand it is equivalent to
cat README | less
- 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
findcommand or a GUI search tool.
- 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!
- 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:
- 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-betapackage. 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.
- Grab a zshrc file. You can either google-and-build one you like, or start from my sample ones:
- 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.
- 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.
- 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.
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!)