This blog post was written for Twilio and originally published on the Twilio blog.
In UNIX-based programming, we often talk about shells, terminals, and the command line interfaces. Bash is probably the most well-known, but there are other widely-used options as well, such as Zsh or the Z shell. Read on to learn more about Zsh and some tips and tricks to optimize your development.
What is Zsh?
Zsh, also known as the Z shell, extends functionality of the Bourne Shell (sh), offering newer features and more support for plugins and themes. Starting with MacOS Catalina in 2019, Zsh became the default login and interactive shell in Mac machines.
Install Zsh
You can install Zsh using Homebrew with brew install zsh
.
While you're at it, you can also install the most popular Zsh plugin, oh-my-zsh, that comes with many built-in plugins and themes using this install script:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
9 Lesser-Known Zsh Tips and Tricks
-
My teammate Valériane Venance tweeted about the
take
command which creates a new directory and changes to it, thus eliminating the need to type the two commandsmkdir
andcd
.take
will also make intermediate directories as needed. -
Searching through history. In the terminal, pressing the up arrow cycles through previous commands you used starting with the most recent first. With Zsh, you can cycle through times you used a specific command, ie.
mkdir
. My wonderful teammate Matthew Gilliard told me aboutctrl-r ___
which finds the last time you searched for the given phrase. Clickingctrl-r
again would find the second most recent, then third, etc. - Automatic
cd
. No need to typecd
to switch directories, just type the directory name. Mass rename files with
zmv
. To install zmv, runautoload zmv
. I downloaded a lot of images for a machine learning model and wanted to rename them to be more consistent (ie. epcot-1.jpg, epcot-2.jpg, epcot-3.jpg… instead of 1.jpg, 2.jpg, 3.jpg...) The command to do so would bezmv '(*).(jpg|jpeg)' 'epcot-$1.$2'
. To check what would happen before running the command, you can add-n
, instead runningzmv -n '(*).(jpg|jpeg)' 'epcot-$1.$2'
What does that command mean?(*).(jpg|jpeg)
finds each file in the directory that ends in either.jpg
or.jpeg
. Thenepcot-$1.$2
says to edit each file name by prependingepcot-
followed by the original file name (represented by$1
) and then the original file type (with$2
).Perform calculations from the command line like a calculator.
-
Bountiful potential plug-ins. As mentioned in the Installation section, oh-my-zsh comes with many plug-ins. You would include the
npm
andsudo
plug-ins by adding this line to your~.zshrc
file:plugins=(npm sudo)
. Some stand-out plug-ins include-
npm
adds auto-complete tonpm
commands. -
sudo
adds--you guessed it--sudo
to a command even after you've typed it by clickingesc
twice. -
zsh-autosuggestions
suggests commands while you type according to your history of previous commands and completions. (web-search
lets you open a search engine from your command line: runninggoogle ___
will search Google for the given phrase, ie. Serena Williams as shown below. -
git
includes many aliases for git commands, letting you type less and save time. Why typegit add
when you can typega
instead? More aliases are listed here.
-
Park a command.
Ctrl-q
"parks" the command you're currently typing and takes you back to the prompt, letting you start over and type another command. Once you run that other command, the original command is un-parked and refills the command line so you can continue--this is good for if you, say, forgot to do a command before a command.
Easily edit a command after you've typed it on the command line. If you've typed or pasted a long command and decide you need to edit it before running,
ctrl-x-e
opens it in an editor (usually vi, but you can set it to be any text editor with the$EDITOR
environment variable.)-
Key combo shortcuts. Type
ctrl l
instead ofclear
to clear your terminal.What's Next for Turbo-Charging your Shell
This is just the beginning--there is so much more you can do with zsh and oh-my-zsh. Check out this oh-my-zsh cheat sheet and this list of ZSH frameworks, themes, and plug-ins maintained by Twilio engineer Joe Block, and let me know online what your terminal looks like!
Top comments (3)
I use
zsh
these days because it comes on my work Macbook, and I've set up my own computers to roughly match the environment. I think it's a good shell.I see a lot of posts about how it's great because it does such-and-such and maybe it's late and I've just watched some people land another robot on Mars, but I want to speak up for the other shells here. So here I go:
zsh
isn't the default shell in newer MacOS releases because it's better thanbash
, it's there because Apple don't want to use GPL software. It seems like a massive improvement to Apple users because the version ofbash
that their systems was running was years and years out of date.The
take
command does not exist for me. It isn't built intozsh
- or not on my copies of it anyway. It would seem like a pretty random thing to include. I'd never heard of it because it's literally something I never do, and if I did, I'd writetake() { mkdir $1 && cd $1 }
in my startup script, which will do what you want and work in most other shells too.This is neat, but I find it more annoying than useful, tbh.
I never use this, partly because what happens if you've got a directory called
ls
? You have to remember to usecd
sometimes which for me is worse. Think you won't have directories with the same names as commands? You will when you build any commands from source :)rename
does this as well, and doesn't needzsh
.That's what
bc
is for :)Ok, plugins (mostly from oh-my-zsh) are what people mostly seem to like.
This does not work for me (I've just tried it on Mac and Linux) and I suspect it's because
ctrl-q
is already a terminal flow control command, so trying to shadow it in the shell is going to fail most of the time. My normal flow for this would bectrl-a
#
enter
to comment out the line but leave it in my history. That works onbash
, and while it doesn't technically work that way onzah
, it's effectively the same because the shell can't find an executable starting with a hash so it just reports it as command not found. As a rule of thumb I will not use a shortcut, alias or quick hack if it's not going to work consistently in all my environments. - because that way lies madness.You can do this in
bash
. In fact, I can't do it inzsh
because my config doesn't come with the right binding out the box... but it's straightforward to add.This is a terminal code that will work in any shell.
Now, I'm not trying to make a list of points simply to rain on your parade; I think that most of these are good things to know. But you don't need
zsh
for most of them!I don't
zsh
for similar reasons to yours in number 7: I definitely can't use it in some of the environments I work in, so I haven't really put any effort into using it anywhere. And I think it's useful to know what comes from where.So, as an addition to this, some notes on equivalents that work in bash:
2: You can set this up for bash using the readline initialisation file
.inputrc
file in your home directory, or using bind commands in your shell startup files. I use the bind method because it doesn't affect other programs using the readline library that way. (E.g. the mysql and sqlite clients.)Ctrl-R also works in bash for expanding partial commands into history entries, though slightly differently.
3: I don't think this is a good idea either, but I thought it might be possible to set up in bash by setting the command-not-found handle:
Unfortunately it turns out this is run in a separate execution context to the shell it comes from, so the
cd
command can't take effect as intended.I'm not sure there's an approach that would work.
7: I do this in bash using the readline kill buffer; usually using Ctrl-A to skip to the beginning of the line, then Ctrl-K to cut the line into the buffer. Then later, I can use Ctrl-Y to paste it back.
These keyboard shortcuts also work in zsh, because although zsh doesn't use the readline library, the equivalent zle apparently implements a lot of the same features.
An extensive plugin library is probably handy, but it's worth knowing that a lot of the stuff in there can also be implemented in bash, and there's an equivalent oh-my-bash to oh-my-zsh.
Zsh's line editing and display capabilities seem somewhat more sophisticated than bash's, definitely, so I think some things just can't be ported. The display-suggestions-as-you-type thing, particularly, I don't think has a bash implementation.
Recently was disappointed when 2 didn't work for me on another laptop, didn't know it's zsh, it's so great tbh, "take" off cause is also supper useful for developer, maybe rarer use case, generally I think would be more useful to list maybe useful things from other shells or some useful bash tips than claim that these tips are not good or not zsh specific