history Command in Linux: View and Manage Bash History

By 

Updated on

13 min read

Linux History Command

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:

txt
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 last n entries in the history list.
  • -c - Clear the history list held in memory.
  • -d OFFSET - Delete the entry at position OFFSET.
  • -d START-END - Delete the entries from START through END.
  • -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.

Terminal
history
output
...
467  git push
468  tail -f var/logs/error
469  nano +22,5 functions.sh
470  source project-env/bin/activate
471  history

Typically, 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 :

Terminal
history | less

To 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:

Terminal
history 5

Use 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:

Terminal
!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:

Terminal
!!

This is especially useful when you forget to prepend a command with sudo , and instead of re-typing the command you can type:

Terminal
sudo !!

The !word expansion executes the most recent command starting with word:

Terminal
!git

Argument Expansions

You can also reuse arguments from the previous command:

ExpansionDescription
!$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:

Terminal
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:

Terminal
^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:

Terminal
history -p "!git"
output
git push

The :p modifier does the same from the expansion itself, although it does add the expanded command to the history list:

Terminal
!git:p

If 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:

Terminal
shopt -s histverify

Check 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:

Terminal
history | grep nano
output
302  sudo nano /etc/resolv.conf
356  nano setup.py
413  sudo nano /etc/hosts
469  nano +22,5 functions.sh

Now, if you want to re-run the nano setup.py command simply type:

Terminal
!356

Another 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:

sh
(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:

Terminal
fc -ln -10
output
	cd /var/www
	git pull
	sudo systemctl restart nginx

fc still indents each line with a tab. To remove the leading whitespace as well, pass the output through sed :

Terminal
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:

Terminal
fc

This opens the last command. To edit a specific command by number:

Terminal
fc 467

To list recent commands without editing, use fc -l:

Terminal
fc -l -10

Saving 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:

Terminal
history -a

The -w option writes the complete history list to the history file.

Terminal
history -w

The -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:

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:

Terminal
history -n

The history file itself is plain text, so you can read it with any pager or editor:

Terminal
less ~/.bash_history

Bash 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:

Terminal
history -c

To 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:

Terminal
history -d 365-375

The 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:

Terminal
history -c
history -w

Modifying 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:

sh
HISTSIZE=10000

The 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:

sh
HISTFILESIZE=10000

If 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:

sh
HISTFILE=~/.bash_history

The 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 both ignorespace and ignoredups.
  • erasedups - removes all previous occurrences of the command from the list before saving it.
sh
HISTCONTROL=ignoreboth

The 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:

sh
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:

sh
HISTTIMEFORMAT="%F %T: "

The history will be displayed in the following format:

output
413  2019-10-27 21:13:07: sudo nano /etc/hosts

Sharing 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:

sh
shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
  • history -a appends new commands to the history file.
  • history -c clears the in-memory history list.
  • history -r re-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=ignoreboth to skip duplicates and commands starting with a space.
  • Using HISTIGNORE to exclude common sensitive patterns.
  • Removing sensitive entries immediately with history -d 365 followed by history -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 .

TaskCommand
Show full historyhistory
Show last 10 commandshistory 10
Run command by number!467
Run previous command!!
Run previous command with sudosudo !!
Last argument of previous command!$
All arguments of previous command!*
Search historyhistory | grep keyword
Reverse searchCtrl+R
Preview an expansion without running ithistory -p "!!"
Show history without line numbersfc -ln -10
Edit and re-run last commandfc
Append session to filehistory -a
Read new lines from the history filehistory -n
Clear historyhistory -c
Delete a specific entryhistory -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.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

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