Shell productivity tricks – the best shortcuts to boost your shell usage

In this article I present over 20 useful keyboard shortcuts and commands that boost your shell productivity (Terminal). Links to the source materials are provided, with tips for reducing mental load caused when trying to adopt too many shortcuts at once.

Introduction

In my Digital tool efficiency article, I discussed why many people use their digital tools in an inefficient way, without even realizing it. In general, there is nothing wrong with “slow living”, doing things consciously slow. However, if you need to frequently perform long-ish tasks which are not particularly exciting, or even annoying, it is very useful to know how to become more efficient or effective. When I use these terms, I mean the following:

  • Effective: “do the right thing” – use features of your digital tools that you did not know before
  • Efficient: “do it the right way” – given a known feature, use mouse- or keyboard-shortcuts to accelerate its use

For developers and DevOps engineers, the shell (or on macOS, the Terminal) is a frequently used tool. The goal of this article is to provide you with useful sources to build your personalized repertoire of efficiency and effectivity tricks for the shell, and a list of my personal favorites.

Sources

When researching useful commands and shortcuts for the shell / Terminal, I primarily used the two following websites (and other websites they link to):

Avoiding mental overload

When going through the websites mentioned above, I felt like a gold digger who keeps finding useful tips. I ended up with a large table of about 30 shortcuts. Then I realized that they are way too many to remember.

Consequently, I limited the shortcuts I actually want to adopt to a minimum. Here are a few helpful criteria to decide which shortcuts to keep:

  • What problem does the command or shortcut solve and how is it better than your current solution? Most websites just throw commands/shortcuts at you, and explain what they do. Such commands/shortcuts are the solution! But which of your problems do they solve? And what inferior approach did you use so far, making the new command/shortcut better?
    • Example: The Ctrl+A shortcut moves the cursor to the beginning of the line. This might solve the problem where you need to fix a typo you made at the beginning of a long command. Before knowing that shortcut, you might moved the cursor by pressing and holding the <arrow-left> key, which might take many seconds to reach the beginning of the line. In this case, the Ctrl+A shortcut does solve a real problem, because it is much faster. On the other hand, suppose you already knew another trick, moving the cursor word-by-word (via Alt+<arrow-left>), which is quite fast. Then, the time savings of Ctrl+A are negligible, and therefore the shortcut might not be worthwhile to remember.
  • How often do you run into the problem? If you cannot vividly remember several occasions in the recent past where you were annoyed by your slow-ish alternative, the shortcut might not be important enough to remember.
  • Is the shortcut a duplicate of another shortcut? For instance, the shortcut Ctrl+P lets you cycle through previously executed commands. But so does <arrow-up>. If you already know a shortcut, there is no point in learning yet another one.
  • Is there an even better alternative? Sometimes the shortcut you find is inferior to yet another shortcut you might discover (or already know). This is criterion is best applied in retrospect, once you collected a number of shortcuts or commands, weeding out those for which there are better alternatives.
    • Example: the shortcut Ctrl+S pauses printing the output of the currently running process (Ctrl+Q resumes printing). This is useful if you need some time to read the output, which would otherwise be impossible if the text kept moving/scrolling. Personally, I found the alternative of using my mouse scroll wheel (scrolling up) much better: in most shells, this stops auto-scrolling of the output, and if I want, I can still scroll down and read output that has appeared in the meantime (since I started scrolling up), which is not possible when using Ctrl+S.

Shortcuts that boost your shell productivity

In this section I present a list of keyboard shortcuts and commands that I personally like and use on a daily basis. Some of these might be useful for you, too. I still encourage you to build your own repertoire!

Disclaimer

The keyboard shortcuts presented above were tested for Linux/Bash (WSL) and may behave differently (or not work at all) in other shells or operating systems! Your mileage may vary.

Working with the shell history

One of the most common problems is that you need to re-run commands that you already ran before. This is possible thanks to Linux’s command history, which keeps tracks of all executed commands. Let’s look at how to access this history, how to modify it and how to search in it. I encourage you to try out these commands right now!

CommandExplanation & Problems solved by the command
historyPrints the previously executed commands in a 2-column table. The first column shows an index number, the second column shows the command itself. That table can be very long, but you can use history n to limit the output to the n most recent commands.

Solved problem: you want to re-run an older command, but you do not remember any part of it, so you do not even know what to search for, and thus you want to visually scan through the list of entries, hoping that you will recognize the command.
!<index>Runs the command with <index> returned by history. Example: !123 
To run the most recent command (the last entry in the table returned by history) you can replace the index with another !, so you only need to type !!

Solved problems:
1) You identified a command in the table printed by history, and you want to re-run it, without having to manually type it in again, or without having to select the command with your mouse to copy it to the clipboard.
2) Running !! is faster than typing the index number. This is especially useful if you forgot to put sudo at the beginning of a command. Running “sudo !!” is easier than “<arrow-up> + <Ctrl+A> + <type 'sudo '>
<Ctrl+R> <search string>Triggers the reverse search feature of the shell. It searches in your command history for the exact sequence of characters (your search query) that you type in after having pressed Ctrl+R. Shows the most recent command first that is matching. To show the second, third, … most recent command, press Ctrl+R repeatedly.

Then press either <Enter> to run the command, or <Tab> to place it in your prompt, so that you can edit it prior to running it. To leave the reverse search, either press Ctrl+C or Ctrl+G.

Solved problem: you want to re-run a previous command of which you remember at least one part (e.g. an argument, or the name of the binary).
history | grep <search-term>Prints only those previously executed commands that match your search term.

Examples:
history | grep docker

history | grep docker.*busybox

The latter returns all commands that contain “docker”, followed by arbitrarily many characters, followed by “busybox”. This would find something like “docker run --rm -it busybox sh

Solved problem: you want to search and retrieve a list of matching commands at a glance (which the reverse search does not offer). And/or you want to use regular expression syntax to search for more complex patterns (which the reverse search also does not support), without any third-party tools like atuin (presented below).
<arrow-up> or <arrow-down>Cycles through the most recently entered commands (you can press it repeatedly).

Solved problem: you want to re-run a very recently executed command.

Note: if you see weird symbols such as ^[[A or ^[[B when pressing the arrow keys, you are most likely using the bare-bones /bin/sh shell instead of a more sophisticated shell like bash.
history -cClears your entire command history (which also affects the reverse search).

Solved problem: you are sharing access to a machine and want to remove all traces of the commands you used, e.g. because they contained credentials.
history -d <index>Deletes only the <index> command from the command history.

Solved problem: you are sharing access to a machine and want to remove a specific command you executed in the past, e.g. because it contained credentials.

Note: if you want to run a command with credentials and want to exclude it from the shell’s command history, just prepend a whitespace character before running your command. For instance, “ echo credential” will not be recorded in the history.

There are also various third-party tools that extend the functionality of your shell, e.g. replacing the reverse search, providing auto-completion for many CLI tools, and much more. Examples are atuin, fzf, starship or zsh-autocomplete. I encourage you to try these tools out!

Editing commands

If you type in a long command, chances are high that you need to edit it, e.g. because you made typos, or provided some arguments in the wrong order. Unfortunately, editing the current command in a shell / Terminal is much harder than, say, editing text in a graphical text editor (such as Microsoft Word). With graphical text editors, you can do things like undo, or select entire words (or lines) and move or delete them easily. For a long time, I thought that this was impossible in the shell, which is why I sometimes crafted long commands in a graphical text editor and then copied them into the shell.

Let’s look at a few useful keyboard shortcuts that make editing commands much easier. There are a lot more of those, of course, offered by the underlying GNU readline library, as this post explains.

CommandExplanation
Ctrl+A

Ctrl+E
Moves the cursor to the beginning (Ctrl+A) or end (Ctrl+E) of the line. Depending on your shell, the <Home> or <End> key might have the same effect, but sometimes these keys do vertical scrolling, instead of moving the cursor.

This is useful when you need to fix mistakes at the beginning of a long command.
Ctrl+CClears the current command. Useful if you want to start from scratch.
Ctrl+<arrow-left>

Ctrl+<arrow-right>
Moves the cursor to the previous or next word.

Note: on some systems / shells, you need to use Alt instead of Ctrl 
Ctrl+WCuts the word that is directly to the left of the cursor.
Ctrl+YPastes the word(s) you most recently deleted, e.g. because you cut it via Ctrl+W

Note: pasting content from the operating system’s clipboard is a different story. That sometimes does not work with the Ctrl+V shortcut that you know from graphical text editors, but requires a right mouse click instead. 
Alt+<Backspace>Deletes the word that is to the left of the cursor.
Alt+<Delete>Deletes the word that is to the right of the cursor.

Note: on some shells, only Alt+D seems to work.
Ctrl+_Undoes the last operation (just like Ctrl+Z does for graphical programs).
fcOpens the most recently executed command in your default (CLI-based) text editor (defined in environment variable $EDITOR). You then edit the command in the editor (more comfortably than in the normal command prompt), then you close and save the file. Then changed command is executed immediately.

This is especially useful for multi-line commands.
Ctrl+X Ctrl+EPress Ctrl+X followed by Ctrl+E to open the current command prompt in your default text editor (see fc).

Job control

In a shell, “job control” refers to “the ability to selectively stop (suspend) the execution of processes and continue (resume) their execution at a later point” (source).

If you already know that you want to run a UNIX process in the background (while typing the command), just add a & sign at the end of the command, e.g. “sleep 60 &“.

If you started a process “normally” (in the foreground) and want to send it to the background as an afterthought (so that you can continue doing other things in your active shell), press Ctrl+z. This puts the active process as job in the background and pauses (suspends) it. Since you most likely did not want to pause it, there are commands to manipulate the state of jobs:

  • bg” unpauses a job (if paused) and keeps it in the background
  • fg” unpauses a job (if paused) and puts it back to the foreground

You can see all active jobs (and their state) with “jobs“.

Miscellaneous

Here are a few more tips that did not fit into any of the above categories:

CommandExplanation
Ctrl+L

clear
Both the “clear” command and the Ctrl+L shortcut clear your terminal from earlier output. While Ctrl+L still lets you scroll back to previous content (e.g. with your mouse wheel), clear does not.
Ctrl+DLogs you out of your active shell. This is faster than typing “exit“.
<Tab> <Tab>Pressing the <Tab> key twice in a row shows all possible options offered by your shell’s auto-complete feature. The “normal” auto-complete mode (pressing <Tab> once) only completes commands/arguments/file names if they are either fully “complete”, or completes it up to the next point of ambiguity.

For instance, if you want to complete file names and your directory contains two files, “file-a” and “file-b”, pressing <Tab> after having typed “fi” only completes until “file-“. Only pressing <Tab> twice will show both files.
cd -Switches back and forth between the current working directory, and the directory you most recently cd‘d to. Very useful if you are doing work in two directories and frequently need to switch back and forth between them, but want to avoid having to type the directory’s path every time.

Adopting keyboard shortcuts and commands

After researching keyboard shortcuts and commands that are so useful that you want to integrate them into your daily life, there is another challenge: actually using and adopting them in daily life. As I discuss here in more detail, I found several adoption methods, each having their up- and downsides.

Keyboard shortcuts are best learned using shortcut trainer apps (like KeyCombiner), while conditioning you to use new features works better with a spaced repetition software such as Anki.

Conclusion

In this piece I presented many tips for improving your shell productivity. This is a lot of material, and I urge you to take it slowly! Changing habits is very difficult, and you will lose the fun or interest if you overburden yourself with implementing too many steps at once. Personally, I just reserve about 30-45 minutes each Monday morning, where I research cool features, or practice the tricks I researched.

In the next post, I will go into how using AI can boost your shell productivity even further.

Leave a Comment