Bash is dead… Long live ZSH!

Over the years I’ve flirted with several different shells. During the 80’s on System V I used csh, later I spent years working on Solaris in tcsh (oooh tab completion!), but as Linux became the main operating system of choice I switched to bash. It seemed like a good choice at the time, as it has several nice features and is the default on most systems, including OS X. However, it wasn’t long until I started noticing the cool new kid on the block: zsh.

I admit, I was originally interested in zsh because of the flashy command prompt I saw co-workers using–wow is that really your laptop battery life displayed as hearts from zelda in the command prompt??–but once I dove in I found all sorts of awesome stuff!

Recursive Globbing

How many times have you been looking for a file but can’t remember where in your home dir it’s stored? You can resort to the find command, but it’s clunky and not very intuitive. Instead with zsh, you can find it quickly and efficiently:

╭─@Sylvains-MacBook-Pro.local ~/temp
╰─ ls -la **/*.txt
-rw-r–r–  1 sylvain  staff  0 Sep 17 17:31 1.txt
-rw-r–r–  1 sylvain  staff  0 Sep 17 17:31 2.txt
-rw-r–r–  1 sylvain  staff  0 Oct  1 13:49 baz/foo/file_im_looking_for.txt

Suffix Aliasing

In GUI interfaces like Windows or OS X you have the ability to double click on a file in order to launch the appropriate application to open that file with. In zsh you can instead set suffix aliases to accomplish something similar:

alias -s rb=vim

Now from my shell I can just type:


And voila, vim will launch and edit the file.

Hash Support

If you do a lot of development in ruby and its compatriots,  you’ve probably come to rely on hashes as a very versatile data structure. After all, being able to work with them in your shell scripts makes them much more powerful and allows you to more intuitively aggregate data instead of having to set up large number of accumulator variables. Additionally you’re able to do things like list all the keys and/or values in the hash, something you can’t do in bash without knowledge of all the variables and explicitly calling each one.

Sexy Command Prompts

I gave you a little teaser earlier but there’s so much more to zsh’s command prompt structure. There’s even a built in theming system if you’re using oh-my-zsh, allowing you to quickly try out a wide variety of prompts. I modified gnzh to suit my purposes, here’s some examples of why it rocks:

╭─@Sylvains-MacBook-Pro.local ~
╰─ cd dev/zsh-battery
╭─@Sylvains-MacBook-Pro.local ~/dev/zsh-battery  (master○)
╰─ touch some-file.rb
╭─@Sylvains-MacBook-Pro.local ~/dev/zsh-battery  (master⚡)
╰─ rm some-file.rb
╭─@Sylvains-MacBook-Pro.local ~/dev/zsh-battery  (master○)

Unfortunately I can’t show you the color changes (aside from the snippet appearing in this piece’s featured image), but I can note the key take aways. For example, my command prompt changes to green when I’m in a git project and displays the branch I’m working with. If my working directory isn’t clean, then the green ○ after the branch name turns into a red ⚡ until I’ve committed or cleaned up my working directory.

Tab Completion…For Anything

Perhaps the most impressive part of zsh is how many plugins are available to support context aware tab completion. The git plugin is an awesome example. Start typing git check and hit tab, you’ll get checkout. Then start typing a branch (or remote!) name and it will tab complete from the available options! This allows me to write very descriptive branch names like fix_admin_invisibility_bug without paying the penalty of typing that out each time I’m going to work on the branch.

Have you found an even better way to utilize zsh in your day-to-day? Leave a comment and let me know!