Command line editing

By default, the Bash shell uses GNU Readline, which provides a set of Emacs-friendly key bindings that are a pretty workable way to edit long and complicated commands. If you learn a little about the chords available to you in editing Bash commands through this library, and combine that with a little old-school command-line magic, you can work at high speed with decent accuracy quite easily. Alternatively, if you don’t like the Emacs-style keybindings and would prefer to stick to a vi-friendly model, you can use set -o vi to edit your command line directly with vi keybindings.

However, if you’re building a particularly complex string of commands involving a lot of pipes, escapes, and redirections, it often turns out to be handy to actually load them into your favourite editor, to give you full facility to edit them in any way you wish. Bash provides a method for this in the form of its Ctrl+X, Ctrl+E binding.

To use it, you can type anything at the command prompt (including nothing at all) and press Ctrl+X, Ctrl+E to bring up your EDITOR, be it Vim, Emacs, or Nano, with the contents of the command line there to edit. As soon as you save and quit, the command will be run as stated, and will be entered into the command history as if you typed it out on the shell directly.

There’s also a handy built-in Bash shortcut, fc (short for “fix command”) to open the previous command in your editor, allow you to edit it, and then run it automatically when you quit. This is particularly useful if you’ve made a small mistake in a complex line of shell code.

If this happens to bring up the wrong editor, perhaps because your choice doesn’t match that of the system administrator, you can set your personal preference of editor like so:

$ export EDITOR=/usr/bin/vim

You can confirm this is working by checking your environment variables:

$ env

One downside of this method is that without special setup within your editor, you lose some of the benefits of things like tab completion. Fortunately it only takes a little creative mapping to make this work in Vim, taking advantage of the Ctrl+X, Ctrl+F file completion that’s already built in. You could even bind that straight to the Tab key if you don’t otherwise use it.

:inoremap <Tab> <C-X><C-F>