What you'll learn
Quick Answer
The shell uses readline key bindings by default, so the same shortcuts work in bash, zsh and tools like the Python REPL and psql. The high-value ones: Ctrl+R to search history, Ctrl+A and Ctrl+E to jump to the start and end of the line, Alt+B and Alt+F to move by word, Ctrl+W to delete the previous word, Ctrl+U and Ctrl+K to cut to the start or end, and !! and !$ to reuse the last command or its last argument.
Move around the line without arrow keys
Holding the left arrow to crawl back to the start of a long command is the slowest thing you do in a terminal. The shell reads these keys instead:
- Ctrl+A: jump to the beginning of the line.
- Ctrl+E: jump to the end.
- Alt+B: move back one word.
- Alt+F: move forward one word.
- Ctrl+B and Ctrl+F: move back or forward one character.
These come from the readline library, which bash uses by default and which zsh mirrors in its default (emacs) editing mode. The same keys work anywhere a program uses readline or libedit: the python and node REPLs, psql, irb, gdb. Once the movement keys are muscle memory you stop thinking about where the cursor is, which is the point. On some keyboards the Alt combinations are sent by the Option or Meta key, or by pressing Esc and then the letter.
Delete and recover text
Editing instead of retyping:
- Ctrl+W: delete the word before the cursor, splitting on whitespace. Good for removing the last path you typed.
- Alt+Backspace: delete the previous word, but splitting on punctuation too, so it stops at
/,-and.. Use it to remove one path segment. - Ctrl+U: cut from the cursor to the start of the line. In bash this is to the start; in zsh's default it cuts the whole line.
- Ctrl+K: cut from the cursor to the end of the line.
- Ctrl+Y: paste (yank) the last thing you cut. Alt+Y cycles through earlier cuts.
The cut text goes to the shell's own kill ring, which is separate from your system clipboard. So Ctrl+U to stash a half-typed command, run something else, then Ctrl+Y to bring it back, all without touching what you copied from the browser. That stash-and-restore move is worth learning on its own.
Ctrl+R: search your history
Ctrl+R starts a reverse search through your command history. Type a few characters from any part of a past command and the most recent match appears. Press Ctrl+R again to step to the next older match, Enter to run it, or Ctrl+G (or Ctrl+C) to cancel and keep your current line. Pressing the right arrow or Ctrl+E drops the match onto the prompt so you can edit it before running.
This replaces almost all of the retyping people do. Instead of remembering the exact docker run line with six flags, search for docker run and pull it back. history prints the numbered list, and !123 re-runs entry 123.
If you run several shells at once and history feels incomplete, that is because by default each shell writes its history when it exits. Setting the shell to append after every command fixes it, and is worth doing early.
History expansion: !! and friends
The shell expands ! patterns before running a line. All of the following were verified in bash:
!!is the previous command.sudo !!re-runs it with sudo after a permission error.!$is the last argument of the previous command:mkdir -p a/b/cthencd !$.!*is all arguments of the previous command;!^is the first.!gitruns the most recent command starting withgit.^old^newre-runs the last command with the firstoldreplaced bynew.!!:gs/old/new/re-runs it, replacing everyoldwithnew.
A cleaner alternative to !$ is Alt+. (or Esc then .), which inserts the last argument of the previous command straight into your line, and repeating it cycles back through the last arguments of earlier commands. The shell variable $_ also holds the last argument, so mkdir build && cd $_ works inside scripts where history expansion is off.
Small ones that add up
- Ctrl+L: clear the screen but keep whatever you have already typed on the line. The
clearcommand clears the screen too, but runs as a command, so it does not preserve a half-typed line. - cd -: switch to the previous directory. Run it again to switch back.
cdwith no argument goes to your home directory. - Ctrl+X Ctrl+E: open the current command line in your
$EDITOR, for building up a long pipeline comfortably. Save and quit to run it. - Ctrl+_: undo the last edit on the line. Repeat to keep undoing. Some terminals send this on Ctrl+/ as well.
- pushd and popd: keep a stack of directories instead of a single previous slot;
dirsshows the stack.
Brace expansion is not a keybinding but belongs here: cp config.yml{,.bak} makes a backup in one step, and mkdir -p src/{api,web,shared} creates three directories at once.
