Enhanced history searching in zsh

Vincent Danen explains how to get more out of the search history features in the zsh shell.

If you spend any length of time in the shell, chances are you've typed the same commands over and over. It's usually not anything you can necessarily script as the commands may vary slightly on each invocation, but there are certain commands that can be used often with a little variation on each call.

Usually these commands are scripts themselves and the arguments passed to them will change over time or with what you are working on.

History searching is handy in these cases. By default, the zsh shell will respond to the [Ctrl]-R key sequence to search through the history based on what you type in. With repeated [Ctrl]-R keys, searching continues backwards for any shell commands that match. Unfortunately, on many terminals, [Ctrl]-S which should do forward searching, does not work so if you accidentally hit [Ctrl]-R one too many times, you're stuck having to abort and do it over again.

This can be remedied by editing the ~/.zshrc file and adding a few bindkey statements:

bindkey "^[[A" history-search-backward

bindkey "^[[B" history-search-forward

These two commands allow for the history to be searched using the up and down arrow keys. To invoke the history search, you must still press [Ctrl]-R which will present the search prompt. Type in the text you want to search for (i.e., perl) and then press the up and down keys without pressing enter.

The search prompt disappears and the command history can be scrolled using the same keys you would use at the command prompt to search through all the shell history. This time, however, only those commands that match the string show up. At this point, if you find the matching command, you can press enter or manipulate the command as necessary.

Another nice feature here is you can use the ! character to invoke the search without pressing [Ctrl]-R. For instance, you could use [Ctrl]-R then type perl and then the up and down arrows to search for all commands with perl in it, or you can use:


instead. This tells the shell to pull up the last command beginning with perl and expand it; now, you can use the up and down arrow keys to cycle through the history, again with the scope limited to those commands that start with perl.

If you happen to enjoy using the vim keybindings in zsh, this will not work. If you execute a search (by pressing [Esc] and then / and entering the search phrase), using the up and down arrows will break out of the search and scroll the full history. You will need to continue using n (next) and N (previous) to scroll the history when using vim keybindings.

About Vincent Danen

Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

Editor's Picks