That perfect 12-flag command you ran last week is one Ctrl-R away — you just never learned to ask.
Ctrl-R won't just find the command — it finds the one you forgot you even typed.
Every interactive bash session appends each line you type to an in-memory list, and on exit writes it to ~/.bash_history. The `history` command prints that list, numbered; `!42` re-runs entry 42; `!grep` re-runs the last command starting with grep. The real unlock is that this isn't a read-only archive — HISTFILE, HISTSIZE, and HISTCONTROL shape what gets remembered and what's silently skipped.
The single most useful terminal habit is Ctrl-R: press it, type two or three characters, and bash walks you back through every matching command you've ever run. Tap Ctrl-R again to go further back, Enter to run. Combined with `!
$ history | tail -6
123 cd /var/log 124 du -sh * 125 find /home -name '*.conf' -size +1M 126 journalctl -u nginx --since today --no-pager 127 sudo apt upgrade 128 history | tail -6
The numbered list. The numbers are the keys: `!125` re-runs that exact find one-liner.
$ !126
journalctl -u nginx --since today --no-pager Sep 20 09:00:02 srv nginx[1282]: 10.0.0.7 - - [20/Sep/2026:09:00:02] "GET /health HTTP/1.1" 200 18
!<n> re-executes command n. Bash echoes the expansion first, then runs it — no ambiguity about what you're firing.
$ tar czf backup-2026.tar.gz src/ $ du -sh !$
du -sh backup-2026.tar.gz 1.2M backup-2026.tar.gz
!$ expands to the last word of the previous command — here the archive filename. `!!` expands to the entire previous line; `sudo !!` reruns it as root.
$ fc -l 20 25
20 ls -la 21 cd projects 22 git status 23 git log --oneline -5 24 cat README.md 25 npm test
fc lists a window of history between two numbers — useful for grepping before you commit a command to a script. fc is also how you edit and re-run a previous command in your editor.
| Flag | Meaning |
|---|---|
-c | Clear the history — both the visible list and the file on exit |
-d offset | Delete the history entry at the given numbered offset |
-a | Append the current-session lines to HISTFILE immediately, instead of waiting for exit |
-w | Write the in-memory history to the file now |
-n | Read new lines since last time from the file, without printing |
-r | Read the file and load its lines into the current session's list |
-p | Perform history expansion on args and print the result, without executing |
History expansion with `!` came from the C shell (csh), written by Bill Joy in 1978. When bash borrowed it, the family split: csh-style `!42` (bang) replays, while bash's newer Ctrl-R search reads the same buffer. Old-timers still argue over which is faster — the `!
Before `history`, Unix had no persistent memory of your commands — you retyped everything, every session. The interactive command history was one of the things that made Unix shells feel alive. bash has kept ~/.bash_history since 1989's first version, and HISTSIZE defaults still cap how many lines survive: on modern bash it's 500 for the running session, 2000 for the file.