# History Tricks: !!, !$ and Ctrl+R

!! runs the last command again and !$ reuses its last argument, sudo !! repeats a command that needed sudo, Ctrl+R steps back through older matches, and four lines in ~/.bashrc keep a longer history that every terminal adds to.

Journeyman · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Rerun the last command with !!, reuse its last argument with !$, and say what sudo !! runs
- Keep a longer history that every terminal adds to, with HISTSIZE, HISTFILESIZE, histappend and history -a

## Key takeaways

- !! (read "bang bang") stands for the whole last command, so !! | wc -l runs it again with a pipe added. bash prints the line it made before running it.
- !$ (read "bang dollar") stands for the last argument of the last command, so after mkdir -p and a long path, cd !$ goes into it.
- sudo !! runs the last command again with sudo. Turn on shopt -s histverify, and bash shows you the line to check before it runs.
- Press Ctrl+R again to step back to older matches, and the right arrow to change a match before you run it.
- HISTSIZE and HISTFILESIZE set how many commands are kept. PROMPT_COMMAND='history -a' saves each one as soon as it runs.

You listed a folder, and now you want to count what's in it. You made a folder four levels deep, and now you want to go into it. A command failed because it needed administrator rights. Each time, the next command is mostly the last one again, and retyping it is where typos creep in. *Your Command History* brought commands back with the up arrow and Ctrl+R. bash also has short codes that stand for parts of your last command, and settings that make the history itself longer and safer. System administrators lean on them all day, because their commands are long and often run twice.

The examples use the practice folder from *Keyboard Shortcuts at the Prompt*: `cd ~/terminal-practice/photo-project`.

## !!: the last command again

`!` is read "bang", so `!!` is "bang bang", and it stands for your whole last command. bash swaps it in before running the line, a step called **history expansion**. List the beach photos, then count them by adding a pipe:

```bash
ls raw/2026/05-may/beach
!! | wc -l
```

```text
IMG_0501.jpg  IMG_0502.jpg  IMG_0503.jpg
ls raw/2026/05-may/beach | wc -l
3
```

The middle line is bash showing you the command it made from `!! | wc -l`, before it runs it. `!!` works anywhere in a line, at the start, the end or the middle.

## !$: the last argument

`!$`, "bang dollar", stands for only the last argument of the last command: often a long path. Make a folder, then go into it without typing the path again:

```bash
mkdir -p exports/print/large
cd !$
pwd
```

```text
cd exports/print/large
/home/sam/terminal-practice/photo-project/exports/print/large
```

Alt+. from *Keyboard Shortcuts at the Prompt* does the same job, but you see the path before you press Enter. `!$` is fewer keys when you're sure. `!!` and `!$` work in zsh too.

## sudo !!: when a command needed sudo

Some commands change the whole computer, so Linux asks you to run them with `sudo` (*sudo and Who Owns a File*). Forget it, and the command answers with *Permission denied*. Typing `apt update`, which refreshes Ubuntu's list of software, without `sudo` does exactly that. `sudo !!` is the famous fix: it runs your last command again with `sudo` in front, here `sudo apt update`.

Because `sudo` runs with full rights, look before it runs. Make sure `!!` is the command you think it is. One setting makes bash show you: type `shopt -s histverify` and press Enter. From then on, a line with `!!` or `!$` isn't run straight away. bash puts the finished line on the prompt instead:

```text
$ sudo !!
$ sudo apt update
```

The second line is waiting, and nothing has run yet. Press Enter to run it (`sudo` asks for your password), or Ctrl+C to drop it.

## Ctrl+R, further back

Ctrl+R searches your history as you type. Two more moves make it better. Run `ls raw/2026/05-may/beach` and `ls raw/2026/04-april/park`, then press Ctrl+R and type `ls raw`. It finds the newest match:

```text
(reverse-i-search)`ls raw': ls raw/2026/04-april/park
```

Press **Ctrl+R again**, and it steps back to the next older match:

```text
(reverse-i-search)`ls raw': ls raw/2026/05-may/beach
```

Press the **right arrow** to put the match on the prompt and change it before you run it, or Enter to run it as it is.

## A longer history that every terminal adds to

Ctrl+R can only find what bash kept. Ubuntu's `~/.bashrc`, the settings file bash reads as each terminal opens, keeps 1,000 commands in memory and 2,000 in `~/.bash_history`:

```bash
grep -n -E '^HIST|histappend' ~/.bashrc
```

```text
13:HISTCONTROL=ignoreboth
16:shopt -s histappend
19:HISTSIZE=1000
20:HISTFILESIZE=2000
```

`HISTSIZE` is how many commands a terminal remembers while it's open, and `HISTFILESIZE` how many the file keeps. `histappend` makes each terminal add its commands to the file instead of replacing it. But each still writes only when it closes, so a terminal that crashes loses its commands, and a new one can't find what the open ones have done. `PROMPT_COMMAND` runs before each new prompt, and `history -a` adds the new commands to the file, so together they save each command as soon as it has run. (`ignoreboth` leaves out repeats, and any line you start with a space.)

Back up `~/.bashrc` first (`cp ~/.bashrc ~/.bashrc.bak`), then open it in nano and add these lines at the end. *Startup Files: .bashrc, .zshrc and source* covers the file in full.

```bash
# A longer history, saved after every command
HISTSIZE=10000
HISTFILESIZE=20000
PROMPT_COMMAND='history -a'
```

Load the changes into this terminal, and check:

```bash
source ~/.bashrc
echo $HISTSIZE $HISTFILESIZE
```

```text
10000 20000
```

Now every command reaches the file at once:

```bash
ls exports
tail -n 2 ~/.bash_history
```

```text
print  web
echo $HISTSIZE $HISTFILESIZE
ls exports
```

On a Mac, zsh's settings go in `~/.zshrc` instead: `HISTSIZE=10000`, `SAVEHIST=20000` and `setopt INC_APPEND_HISTORY`.

## Check yourself

2 questions to try on the lesson page.

## So what

`!!` and `!$` reuse what you typed a moment ago, `sudo !!` fixes a forgotten `sudo` (after a look), and a longer history means Ctrl+R finds the command you ran last month.

## Key terms

- [Command History](https://www.ask-codey.com/glossary/command-history)
- [History Expansion](https://www.ask-codey.com/glossary/history-expansion)
- [sudo](https://www.ask-codey.com/glossary/sudo)
- [.bashrc and .profile](https://www.ask-codey.com/glossary/bashrc-and-profile)

## Cheat sheets

- [History Tricks: !!, !$ and Ctrl+R](https://www.ask-codey.com/cheat-sheets/bash-history-tricks-cheat-sheet)

## Related

- [Your Command History](https://www.ask-codey.com/lessons/bash-command-history)
- [Keyboard Shortcuts at the Prompt](https://www.ask-codey.com/lessons/bash-keyboard-shortcuts)

Source: https://www.ask-codey.com/lessons/bash-history-tricks
