Using vi-mode in your shell

Get an introduction to using vi-mode for line editing at the command line.
432 readers like this.
An introduction to GNU Screen

As a participant in the greater open source community, and more specifically as a member of the Fedora Project, I have the opportunity to meet with many people and talk about all kinds of interesting technical topics. One of my favorites is the "command line," or shell, because learning about how people use the shell proficiently can give you an insight into how they think, what kind of workflows they favor, and to some extent what makes them tick. Many developers and systems operators share their "dot files" (a common slang term for their shell's configuration files) publicly out on the Internet, which leads to an interesting collaboration opportunity that allows everyone to learn tips and tricks from seasoned veterans of the command line as well as share common shortcuts and productivity boosters.

I'll introduce one for you here by showing the shell's vi-mode.

In the large ecosystem of computing and operating systems, there are many shells. However, in the Linux world, the de facto standard has become bash and it is the default shell installed on all major Linux distributions at of the time of this writing. As such, that is the shell I'll be talking about today. Something to note, though, is that bash is also a reasonably popular option on other UNIX-style operating systems, so it's likely not far from your reach (and for you Windows users out there, there's always cygwin).

While exploring the shell, the first thing you do is type commands into it and most often get output, like so:

$ echo "Hello World!"
Hello World!

This is common practice and is probably something everyone reading this has done. Something that newcomers and novices alike might not realize is that the default input mode for the bash shell is Emacs, which means that all line-editing functions you will carry out on commands will use "Emacs-style" keyboard combinations. (For those interested in the nuts and bolts of things, the function of line-editing is actually carried out by GNU Readline.)

For example, if you had typed echo "Hello Wrld!" and realized that you wanted to quickly jump back one word (space delimited) to fix that typo without having to hold down your left arrow key then you would hit the Alt+b keys together and the cursor would jump backward to the W.

$ echo "Hello Wrld!"
        Cursor is here.

This was done using only one of the many Emacs keyboard combinations that is offered to the user of the shell. There are many more available for all kinds of things, such as copying text, pasting text, removing text, and using shortcuts to edit text. Using complex keyboard combinations and committing them to memory may seem silly, but they can be extremely powerful when working with longer commands or recalling a command from your shell history yet wanting to edit a couple things before executing the command again.

While Emacs key bindings are all well and good if you're familiar with the Emacs text editor or otherwise find them convenient to use, there are those who are more comfortable using "vi-style" keyboard bindings because of their time spent in the vi text editor (normally via vim or nvim these days). The bash shell (again, via GNU Readline) is able to provide this functionality for us. In order to enable it, you run the command $ set -o vi.

Just like magic, you're now in vi-mode and can easily line-edit using vi-style key bindings in order to copy text, remove text, and jump around to different positions in the line of text. This isn't much different in terms of capabilities of Emacs-mode but it's how you interact with the shell to perform these actions that changes, which is a powerful option pending your specific preference.

Let's take a look at the same example as before, but with the context that as soon as you land in vi-mode in your shell you're in INSERT mode, which means you can type commands just you did before but you can now hit the Esc key on your keyboard and you'll be in NORMAL mode, which is where you can navigate around freely and make text modifications.

Looking at the same example as before, if you had typed echo "Hello Wrld!" and realized you wanted to jump back one word (again, space delimited) to fix up that typo, then you would hit Esc to change from INSERT to NORMAL mode. Then you can type B (Shift+b for those following along at home), which would move the cursor back much like it did before. (For more information on vi-modes, go here.):

$ echo "Hello Wrld!"
        Cursor is here.

Now, for the vi/vim/nvim users out there this is hopefully a fun "ah ha!" moment when you realize the potential of keeping your tried and true keyboard shortcuts close by at all times and not just while your writing things like code or documentation in your editor. If this is all new to you and you want to learn more, then I might suggest taking a trip to this interactive vim tutorial and see if the vi style of editing text is something you find useful.

If you enjoy interacting with your shell in this mode, you can set that persistently by editing the ~/.bashrc file in your home directory and adding the following line at the bottom.

set -o vi

For the emacs mode users, hopefully this was a quick and fun look into "the other side" of your shell. At the end of the day I think everyone should use whatever editor and shell line-editing mode that makes them most productive and if that's vi-mode and this article was news to you, then congratulations! Now go forth and be productive.

Happy hacking...

User profile image.
Adam Miller is a member of the Ansible Engineering Team at Red Hat focusing on the Ansible Core runtime, Linux system administration automation, container orchestration integrations, and Information Security automation. Adam has completed his Bachelors of Science in Computer Science and Masters of Science in Information Assurance and Security, both from Sam Houston State University.


I have been doing this for years. Because vi is my editor of choice, I find navigating the command line in vi mode much more natural.

Thanks for the super article.

Same here, I'm a big fan of vi-mode myself and hoped to share with others in a (hopefully) fun and friendly way. Thank you for the kind words!

In reply to by dboth

Cool stuff, thanks for sharing!

"However, in the Linux world, the de facto standard has become bash and it is the default shell installed on all major Linux distributions at of the time of this writing."

...To the best of my knowledge Ubuntu has for some time used dash as its default shell.

Default interactive shell for Ubuntu is still bash, dash is used for executing anything with #!/bin/sh which provided a faster shell for POSIX sh use cases (such as SysV init and Upstart daemon scripts).

In reply to by Jerome Covington (not verified)

I prefer to make it the other way around. Start vim, write commands and the pass to the shell through
:! bash
Nothingless this is great for vim fans!

I happen to be more of an Emacs junkie than a huge Vi fan, but I know both editors and can readily use either one.

I'll use Vi or Vim for certain tasks and I'll also use see, awk, Perl, or even Ed at times, sometimes just to keep them in practice, but also at times to use the right tools for the tasks I'm performing.

Great to have all of these excellent tools available!

Another useful tip is putting 'set editing-mode vi' into .inputrc . This will allow some programs with their own command prompt to also work like vi. The one that comes to mind is the mysql prompt but there are others as well.

Being a stubborn vi user myself I have to admit that almost always the first command I issue, after having logged into a Bash-like shell, is "set -o vi", in order to be the least bit productive at the command line, for I am such a lousy keyboard typer (i.e. effectively only using 6 of my 10 fingers at maximum).
Without the shell's history and vi editing mode I would be hopelessly lost like being jailed in a csh.
But instead of solely having to rely on "set -o vi" there is another relief for klutzes like me.
You can resort to readline by editing a .inputrc file in your HOME (or any other file to which the INPUTRC environment variable would refer to) an put in there the these two stanzas:

set editing-mode vi
set keymap vi

As root you could even set this globally in /etc/inputrc (provided you have no dissenting users) .

Another benefit from using these readline settings is that any program or CLI tool which is readline-gnostic automatically provides you with a vi-style mapping and editing mode, which makes working with these tools equally pleasant.

Thank you for the information in your article.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.