Mastering Bash History and Expansion
Published September 9, 2026 · Updated September 9, 2026
View last change
8585ce3 — fix: fix table
History is a Bash builtin command that allows you to view, modify, and delete bash commands that have been run on the system.
Problem it solves
When you work a lot from the command shell, you probably make a lot of typos or need to re-run commands repeatedly. Bash history gives the possibility to view, modify, and delete previously used commands.
How it works
You can check this by running the following command:
# running 'which history' for me doesn't show any output (It can different output on other systems)
which history
# when typing `type history` it will tell you that the command is a shell builtin
type history
> history is a shell builtin
When a new session starts, the history file is loaded and new lines are stored in the current session’s memory. When the session is closed the list is written to disk. By default Bash uses the file ~/.bash_history to save the history to disk. The file will be overwritten by default. To append new lines you have to add the follow line to your .bashrc file shopt -s histappend.
You can configure a custom file by adding
HISTFILEvariable in.bashrcusing theHISTFILEsetting.
If you work a lot in different sessions, for example when you use tmux, the history is not synchronized, because the history lives in memory of the session. You can use the special variable PROMPT_COMMAND to append and load history lines from the history file after each command. To write lines directly to file you can add the following line to your .bashrc PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
Why adding the $PROMPT_COMMAND at the end of the command?
This is to preserve everything already in the $PROMPT_COMMAND variable. If you don’t add this to the command, everything already in $PROMPT_COMMAND will be replaced by history -a; and this can break other stuff.
PROMPT_COMMANDis a special variable that runs every time before bash prints your prompt. So by starting bash or after running a command bash creates a new prompt. All the content within the variable will be run.
Extend the prompt command with history -n; so new commands added from another session are automatically added to your current session’s history.
Below is an example of .bashrc with custom history settings:
# don't put duplicate lines or lines starting with space in the history.
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# setting history length
HISTSIZE=1000
HISTFILESIZE=2000
shoptis another bash builtin used to enable and disable bash specific extensions. There are a few extensions available for the history. for example you can enablehistverifyto let you review the command before running.
The follow shortcuts work with the history directly from the prompt:
| Bash history shortcuts | Description |
|---|---|
| arrow up | go up through your sessions history |
| arrow down | go down through the sessions history |
| ctrl+R | search through the sessions history |
Frequently used history commands are:
| Bash history command | Description |
|---|---|
| history -a | Append the session history to the history file |
| history -w | Overwrite the current session history to the history file |
| history -r | Read the history file into the current session’s memory |
| history -n | Read only new lines and add them to the session’s memory |
| history -c | Clears the session memory list (not the file) |
| history -cw | Clears the session memory and write to file (clears the file also) |
| history [n] | Shows the last [n] commands |
| history -d offset | Removes lines [offset] from the list |
History expansion
With history expansion you can reference and reuse previous commands using the ! expanding the command before it is executed.
A few examples are:
| Bash history expansion command | Description |
|---|---|
!! | the previous command in history |
!N | number N in history |
!-N | the N-th command back from now |
!ping | the most recent command starting with “ping” |
!$ | the last argument of the previous command |
!^ | the first argument of the previous command |
!* | all arguments of the previous command |
> history
# Output
1 clear
2 echo "Hello World!"
3 echo "Hello to the World!"
4 echo "Hello to the World!" > world.txt
5 history
> !2
echo "Hello World!" # expands to: echo "Hello World!"
# output
Hello World!
When I’d reach for it
Because I work a lot in the shell I constantly fall back to my history.
Gotchas
When requesting the man page for history I was a bit thrown off at first because it returned a detailed man page. This is actually the library functions used by programmers. For example Bash is using this library for there history implementation.
# when typing `type history` it will tell you that the command is a shell builtin
type history
> history is a shell builtin
To find the history documentation for bash you have to search through the man pages of bash itself.
# open the man pages for bash
man bash
# use / to search for patterns
/HISTORY
# use n to continue to the next
n
Key takeaway
The history and history expansion commands are tools that if you master the basics, it helps to be more productive and work faster on the shell. It is a quick way to reuse, and even manipulate previous commands to your benefits.
Questions or thoughts about this post? Reach me at jacky@tenrok.nl or on LinkedIn.