history Command in Linux: View and Manage Bash History

If you spend a lot of time on the command line, viewing the history of the commands you have previously run can make your day-to-day work easier and improve your productivity.
In this article, we will cover the history command, which allows you to view a list of previously executed commands, search through the list, and manipulate the history file.
history Command Syntax
The syntax for the history command is:
history [n]
history -c
history -d OFFSET
history -d START-END
history [-anrw] [FILENAME]
history -p ARG [ARG ...]
history -s ARG [ARG ...]n- Display only the lastnentries in the history list.-c- Clear the history list held in memory.-d OFFSET- Delete the entry at positionOFFSET.-d START-END- Delete the entries fromSTARTthroughEND.-a [FILENAME]- Append new lines from the current session to the history file.-n [FILENAME]- Read the lines that have not already been read from the history file and append them to the current list.-r [FILENAME]- Read the history file and append its entire contents to the current list.-w [FILENAME]- Write the current history list to the history file.-p ARG [ARG ...]- Expand the arguments and print the result without running them or storing the expanded result.-s ARG [ARG ...]- Append the arguments to the history list as a single entry.
When FILENAME is omitted, Bash uses the file set by HISTFILE, which defaults to ~/.bash_history.
Using the history Command
history is a shell builtin, and its behavior may slightly differ from shell to shell. We will cover the Bash builtin version of history. If you use Zsh, the concepts are similar but the history file defaults to ~/.zsh_history and some options differ.
In its simplest form, when invoked without any option or argument, the history command displays the whole history list with line numbers.
history...
467 git push
468 tail -f var/logs/error
469 nano +22,5 functions.sh
470 source project-env/bin/activate
471 historyTypically, history displays many lines of output that do not fit on the screen. To view the output one page at a time, pipe it to a pager program like more or less
:
history | lessTo display the last n lines, pass the number as an argument to the command. For example, to view only the last five lines from the history list you would type:
history 5Use the Up and Down arrow keys to navigate through previously executed commands. When the command you are looking for appears, press Enter to execute it.
History Expansions
Bash provides several expansion shortcuts to re-run commands from the history list.
Typing !n executes the nth command from the history list, and !-n the command n lines back. In the following example we are executing the command on line 467:
!467!-1 is the same as !! and executes the last command from the history list, !-2 the second to last, and so on.
Type !! to execute the previous command:
!!This is especially useful when you forget to prepend a command with sudo
, and instead of re-typing the command you can type:
sudo !!The !word expansion executes the most recent command starting with word:
!gitArgument Expansions
You can also reuse arguments from the previous command:
| Expansion | Description |
|---|---|
!$ | Last argument of the previous command |
!^ | First argument of the previous command |
!* | All arguments of the previous command |
For example, if you just ran ls -la /etc/nginx, you can quickly open the same path with:
cd !$Quick Substitution
^word1^word2^ allows you to re-run the last command replacing “word1” with “word2”. If you accidentally typed sduo command instead of sudo command, you can fix it with:
^sduo^sudo^Previewing an Expansion
Expansions run the moment you press Enter, which is risky when you are not certain which command !git or !-3 will match. The -p option expands the argument and prints the result without running it or adding it to the history list:
history -p "!git"git pushThe :p modifier does the same from the expansion itself, although it does add the expanded command to the history list:
!git:pIf you would rather have this check happen every time, enable the histverify shell option. Bash then loads the expanded command into the prompt instead of executing it right away, so you can read it over or edit it before pressing Enter:
shopt -s histverifyCheck the Bash manual for more information about History Expansion , modifiers, and designators.
Searching the History
Use the grep
command to filter the output. For example, to view all commands including “nano” you would run:
history | grep nano302 sudo nano /etc/resolv.conf
356 nano setup.py
413 sudo nano /etc/hosts
469 nano +22,5 functions.shNow, if you want to re-run the nano setup.py command simply type:
!356Another way to search through the command history is by pressing Ctrl+R. The prompt will change to the following, and you can start typing to search for a previously executed command:
(reverse-i-search)`':The shell will display a matching line. To move to the next match, press Ctrl+R again.
History Without Line Numbers
The line numbers are what make !n work, but they get in the way when you want to copy a block of commands or save them into a script. The fc builtin prints the same list without them when you combine the -l and -n options:
fc -ln -10 cd /var/www
git pull
sudo systemctl restart nginxfc still indents each line with a tab. To remove the leading whitespace as well, pass the output through sed
:
fc -ln -10 | sed 's/^[[:space:]]*//'You will often see history | cut -c 8- suggested for this. Avoid it, because it assumes the line numbers are always the same width. That assumption breaks when the history number reaches 100000, and it breaks immediately if HISTTIMEFORMAT is set, since the timestamp shifts every command further to the right.
Editing History with fc
The fc builtin lets you open a previous command in your default text editor ($EDITOR), edit it, and execute the modified version when you save and close the file:
fcThis opens the last command. To edit a specific command by number:
fc 467To list recent commands without editing, use fc -l:
fc -l -10Saving the History List
By default, when starting a new session, Bash reads the history list from the ~/.bash_history file. The list of commands executed in the current session is kept in memory and saved to the file when the session is closed.
If you opened several shell sessions, only the history of the session that is closed last is saved.
The -a option allows you to append the current session history list to the ~/.bash_history file:
history -aThe -w option writes the complete history list to the history file.
history -wThe -r option works in the other direction. It reads the history file and appends its entire contents to the list in memory, which is how a session picks up commands that were written by a different terminal:
history -r-n is the more selective version of the same idea. It reads only the lines that have been added to the file since the current session last read it, so you pull in new commands without duplicating the ones you already have:
history -nThe history file itself is plain text, so you can read it with any pager or editor:
less ~/.bash_historyBash normally stores each history entry on one line. If the lithist shell option is enabled, multiline commands can span several lines instead.
If HISTTIMEFORMAT is set, Bash also writes a timestamp line before each history entry, marked with a leading # and stored as seconds since the Unix epoch. Those lines are metadata rather than commands, which is why the file may look like it contains twice as many entries as you expect.
Clearing History
The history command allows you to clear the complete history list or remove certain parts.
To clear the history list, use the -c option:
history -cTo delete a specific line or lines between a starting and ending position from the history list, use the -d option.
For example, to remove the lines between 365 and 375 (including those lines), you would type:
history -d 365-375The range form of -d requires Bash 5.0 or later. On older versions, you can only delete one line at a time.
If you provide only one number to the -d option, the command removes the given line.
When a negative integer is used, the lines are counted back from the end of the history list.
The commands above clear the history list, which is kept in memory, but do not remove entries from the ~/.bash_history file on disk. To clear the file, you need to write the history list to the file:
history -c
history -wModifying History Behavior
The behavior of the Bash history can be defined using several different environment variables
. When modifying the history behavior, set the variables in ~/.bashrc or any other configuration file which is loaded when the user logs in.
By default Bash keeps 500 lines in the command history list, though many distributions override this to 1000 or more. The HISTSIZE variable controls how many commands are kept in memory during a session. To set it to 10000 add the following line to your ~/.bashrc file:
HISTSIZE=10000The HISTFILESIZE variable controls the maximum number of lines stored in the history file on disk. When a session ends, Bash truncates the file to this many lines. To keep the same number as HISTSIZE:
HISTFILESIZE=10000If HISTFILESIZE is unset, the history file is never truncated.
The HISTFILE variable defines the path to the history file. By default it is set to ~/.bash_history:
HISTFILE=~/.bash_historyThe HISTCONTROL variable accepts a colon-separated list of values that define how the commands are saved in the history list:
ignorespace- commands that start with space are not saved in the history list.ignoredups- duplicate commands are not saved.ignoreboth- is a shorthand, including bothignorespaceandignoredups.erasedups- removes all previous occurrences of the command from the list before saving it.
HISTCONTROL=ignorebothThe HISTIGNORE variable is a colon-separated list of patterns used to decide which commands should be excluded from the history. For example, to ignore ls, cd, and history commands:
HISTIGNORE="ls:cd:history"When the HISTTIMEFORMAT variable is set, Bash prepends a timestamp of execution for the command on each line.
For example, if you set:
HISTTIMEFORMAT="%F %T: "The history will be displayed in the following format:
413 2019-10-27 21:13:07: sudo nano /etc/hostsSharing History Across Terminal Sessions
By default, when multiple terminals are open, each session maintains its own history in memory. Only the last session to close writes to the history file, overwriting what other sessions saved.
To share history across all open terminals, enable the histappend shell option and configure your prompt to save and reload history:
shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"history -aappends new commands to the history file.history -cclears the in-memory history list.history -rre-reads the history file into memory.
Add these lines to your ~/.bashrc to make them permanent.
Security Considerations
Command history can store sensitive data like passwords, tokens, or private URLs. Avoid pasting secrets into the shell, and consider:
- Setting
HISTCONTROL=ignorebothto skip duplicates and commands starting with a space. - Using
HISTIGNOREto exclude common sensitive patterns. - Removing sensitive entries immediately with
history -d 365followed byhistory -w.
Troubleshooting
History is empty after a terminal crash
Bash writes the in-memory list to ~/.bash_history when the shell exits. A normal EOF or SSH disconnect lets Bash exit and save the list. History can be lost when Bash cannot complete its exit, such as after SIGKILL, a shell crash, or a power loss. Run history -a as you go, or set PROMPT_COMMAND as shown above so the file is updated after every command.
history -c did not delete anything
The -c option clears only the list held in memory. The file on disk stays as it was until you write to it, so follow it with history -w.
Commands disappear when several terminals are open
Each session keeps its own list and overwrites the file when it exits, so the last session to close wins and the others lose their commands. Enable shopt -s histappend so sessions append to the file instead of replacing it.
history -d 365-375 returns an error
Deleting a range requires Bash 5.0 or later. Check your version with bash --version. On older releases, delete one entry at a time and start with the highest number, because removing an entry renumbers everything after it.
HISTSIZE has no effect
Something is resetting the variable after your change. Distributions commonly set HISTSIZE in /etc/profile or /etc/bash.bashrc, and a value set there can be overridden later in the login sequence. Confirm what the running shell actually has with echo $HISTSIZE, then make sure no file loaded after ~/.bashrc sets it again.
Commands still appear after adding them to HISTIGNORE
Each HISTIGNORE pattern has to match the complete command line, since Bash does not append an implicit wildcard. The pattern ls therefore matches a bare ls and nothing else. Use ls* to exclude ls -la and the rest of its variants.
Quick Reference
For a printable quick reference, see the Bash cheatsheet .
| Task | Command |
|---|---|
| Show full history | history |
| Show last 10 commands | history 10 |
| Run command by number | !467 |
| Run previous command | !! |
| Run previous command with sudo | sudo !! |
| Last argument of previous command | !$ |
| All arguments of previous command | !* |
| Search history | history | grep keyword |
| Reverse search | Ctrl+R |
| Preview an expansion without running it | history -p "!!" |
| Show history without line numbers | fc -ln -10 |
| Edit and re-run last command | fc |
| Append session to file | history -a |
| Read new lines from the history file | history -n |
| Clear history | history -c |
| Delete a specific entry | history -d 365 |
FAQ
How do I prevent a command from being saved to history?
Start the command with a space (e.g., secret-command). This works when HISTCONTROL includes ignorespace or ignoreboth.
Where is the history file stored?
By default it is stored in ~/.bash_history. You can change this with the HISTFILE environment variable.
What is the difference between HISTSIZE and HISTFILESIZE?HISTSIZE controls how many commands are kept in memory during a session. HISTFILESIZE controls how many lines are stored in the history file on disk.
How do I share history across multiple terminal sessions?
Enable shopt -s histappend and set PROMPT_COMMAND to save and reload the history file on each prompt. See the “Sharing History Across Terminal Sessions” section above.
How do I remove a specific command from history?
Use history -d 365 to delete a single entry, then history -w to persist the change to disk.
Conclusion
The history command displays a list of previously executed commands and provides shortcuts to re-run them quickly. Combined with environment variables like HISTSIZE, HISTFILESIZE, HISTCONTROL, and HISTIGNORE, you can customize history behavior to fit your workflow.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page