# Shell history tips

If you're a dev who is new to the terminal, or rarely uses it, you probably
don't know much the shell's history and how to use it to your advantage.

Time to change that by teaching you some tricks I use everyday.

## Hit <kbd aria-label="Control">⌃</kbd>+<kbd>R</kbd> to search the history

Hey you, the dev hitting the <kbd aria-hidden="true">↑</kbd> (Up Arrow) key a
hundred times to search for a command you typed yesterday, stop that. You’re
just wasting your time!

Instead, hit <kbd aria-hidden="true">⌃</kbd> (Ctrl) + <kbd>R</kbd> and type
keywords to search your history. (And nope, it’s not
<kbd aria-hidden="true">⌘</kbd> [Cmd] on macOS—it’s still <kbd>⌃</kbd>.) It's
your terminal's time machine.

The more you use it, the faster it’ll be engrained in your muscle memory to the
point you’ll never think of hitting <kbd aria-label="Up Arrow">↑</kbd> anymore.
Instead, let’s say you’re looking for the last `ls` command you typed, you’ll
hit <kbd aria-label="Control">⌃</kbd>+<kbd>R</kbd> then `ls` and you’ll find it
right away.

The command history is a feature found in most shells enabled by default,
including _Zsh_ and _Bash_.

## Command notes with `#`{:aria-label="Hash"}

You typed a long complex command, maybe one that uses sed or awk or grep. You’d
like to save it for later, but since it’s using a program you use often, you’re
worried searching for it with <kbd aria-label="Control">⌃</kbd>+<kbd>R</kbd>
won’t be enough to find it. You’ve probably did many trials and errors to come
up with the correct command, and you don’t want to lose it and have to go
through the process again.

Here’s one thing you can do to help yourself. Once you’ve typed the correct
command you want to save, add a comment at the end:

```sh
echo hello-world | sed -E 's/-/_/g' # Convert all dashes to underscores
```

Like in shell scripts, the part of every line starting with a `#`—which is
prefixed by a space if it’s not the first character of that line—is ignored.
Meaning the above adds a comment to a command, like a note, which will be saved
in history and is searching later. If you type the example above and do Ctrl+R
then type “underscore,” that command will show up again. That’s much easier to
find than having to go through a hundreds of `sed` commands you’ve tested before
it.

## Prepare a command for later

Extending the comment tip above, there are times you are writing a long command
with dozens of arguments, but then you need to clear it because you just
realised you need to run something else first. However, you don't want to lose
what you just wrote!

You may copy and paste the command out of your terminal into a text file or
something. But there's a simpler way.

Just go back to the beginning of the line, add a `#`{:aria-label="Hash"}, to
turn the whole line into a comment that will be remembered—and be searchable—in
your history:

```sh
# ffmpeg -i input.mp4 -filter:v "crop=in_w:in_h-50,crop=ceil(in_w/2)*2:ceil(in_w/16*9/2)*2"

# ^ The `#` in front saves the command as a comment in the history.
```

When you want to use that command, search for it with
<kbd aria-label="Control">⌃</kbd>+<kbd>R</kbd>, go back to the beginning of the
line, and remove the `#`{:aria-label="Hash"} and any leading space—because if
you keep the space in, remember, the command will be excluded from the
history—then run it!

## Repeat the last command with `!!`{:aria-label="Double Exclamation Mark"}

Sometimes you wrote a long complicated command, but then you need to run it one
more time with an extra argument or with `sudo`. Instead of searching for the
command in the history and edit it, simply use `!!`{:aria-label="Double
Exclamation Mark"}. That will get replaced by the previous command you ran:

```sh
vim /etc/hosts
sudo !! # Run the last command, `vim /etc/hosts`, with sudo.

bundle show sinatra
cd `!!` # Run `bundle show sinatra` again, but use its output with `cd`.
```

**Bonus:** For repeating the same command with `sudo`, you may also want to look
into plugins available for your shell. For example, the `sudo` plugin for
[_Oh My Zsh_](https://ohmyz.sh) lets you hit <kbd>Esc</kbd> to repeat the last
command with `sudo`.

## Exclude from history with a space

Keeping your commands in a history forever is great for later reference, but
what if there are commands you don’t want to save? Maybe you’re inputting a
command that has a secret key in it or some private details.

Simple. Prefix your command with a blank space. If a line begins with a space
(` `), it will act like your prompt’s incognito mode and will not save the
command in history:

```sh
# Command saved in history
echo "I'm in your history"

# Command not saved in history
 echo "I'm not in your history"
# ^ Notice the blank space at the beginning.
```

However, that behaviour is set by default maybe only 95% of the time in every
shell—test it first before you use it. If it’s not active, check your shell’s
documentation on how to enable it.

Also, keep in mind that any private information you type on the command line
will likely be visible in the `ps` process listing while the command is running.
The space prefix only affects history, not process listings.

## Select files with `fzf`

This is not related to the history, but it's something that really falls in line
with searching.

[`fzf`](https://github.com/junegunn/fzf) is a command-line fuzzy finder. Once
installed, while typing a command, it lets you search for files in the current
directory by hitting <kbd aria-label="Control">⌃</kbd>+<kbd>T</kbd>.

## Better history with Atuin

You can take your command history further by replacing it with
[Atuin](https://atuin.sh). That tool imports your history from your favourite
shell and replaces it to save any new command you’ll input. Everything is stored
in a SQLite database and you can easily search through commands you’ve input for
years.

Atuin also lets you sync that database in their cloud, so you can use the same
history on multiple machines. Although, I’m not fond of that solution, using it
is up to you. You can also set up your own syncing server.

Anyway, I hope these tips help. If anything, at least remember to use
<kbd aria-label="Control">⌃</kbd>+<kbd>R</kbd>! ;)
