|

Linux CLI 16 – history ๐Ÿง

The shell remembers the commands you’ve typed โ€” this is called command history. It’s one of the most productivity-boosting features of the command line, letting you recall, search, and rerun past commands instantly.


How History Works

Every command you enter is saved to a history list:

  • Kept in memory for the current session
  • Written to a history file (~/.bash_history) when the shell exits
  • Loaded back when you start a new session

Default behavior:

  • History file: ~/.bash_history
  • Default size: 500โ€“2000 commands (depends on distro)
  • Navigate with โ†‘ / โ†“ or Ctrl + R

Viewing History

history
history | less
history 10
history -c
CommandDescription
historyShow all commands in history
history | lessView history one page at a time
history 10Show the last 10 commands
history -cClear the current session’s history

Examples

View all history:

$ history
    1  pwd
    2  ls -la
    3  cd /var/log
    4  cat syslog
    5  grep "ERROR" syslog
    6  cd ~
    7  history

View with pagination:

$ history | less
# Navigate with PgUp, PgDn, โ†‘, โ†“
# Press q to quit

View last N commands:

$ history 10
  501  ls
  502  cd projects
  503  git status
  504  git add .
  505  git commit -m "update"
  506  git push
  507  cd ..
  508  pwd
  509  ls -la
  510  history 10

Clear history for the current session:

$ history -c
$ history
    1  history
# Only the current command remains

Re-executing Commands

The ! operator โ€” bang โ€” recalls commands from history.

SyntaxAction
!!Run the last command
!5Run command at position 5
!-2Run the command 2 back
!stringRun the last command starting with string
!?stringRun the last command containing string
!$Use the last argument of the previous command
!*Use all arguments of the previous command

!! โ€” Last Command

Reruns the most recent command.

$ ls /var/log
alternatives.log  apt  auth.log  syslog

$ !!
ls /var/log
alternatives.log  apt  auth.log  syslog

Useful case โ€” forgot sudo:

$ apt update
E: Could not open lock file - open (13: Permission denied)

$ sudo !!
sudo apt update
# โœ… Runs with sudo

!N โ€” Command by Number

Run a specific command from history by its number.

$ history
  501  ls -la
  502  cd /var/log
  503  cat syslog

$ !502
cd /var/log
# โœ… Runs "cd /var/log"

!string โ€” By Prefix

Run the last command that starts with string.

$ history
  498  git status
  499  git add .
  500  git commit -m "update"
  501  ls

$ !git
git commit -m "update"
# โœ… Runs the last command starting with "git"

Example:

$ alias ll='ls -la'
$ alias la='ls -A'
$ alias
alias la='ls -A'
alias ll='ls -la'

$ !alias
alias
# โœ… Reruns "alias"

!?string โ€” By Substring

Run the last command containing string (not just starting with).

$ history
  495  cd /home/kronos/projects
  496  ls
  497  vim app.js
  498  node app.js
  499  npm start

$ !?projects
cd /home/kronos/projects
# โœ… Runs the last command containing "projects"

!$ and !* โ€” Reuse Arguments

SyntaxMeaning
!$Last argument of the previous command
!*All arguments of the previous command

Example โ€” !$:

$ mkdir my-project
$ cd !$
cd my-project
# โœ… Uses "my-project" from previous command

Example โ€” !*:

$ ls -la /var/log /etc
$ echo !*
echo /var/log /etc
/var/log /etc

Practical use:

$ cp /home/kronos/notes.txt /backup/
$ ls -l !$
ls -l /backup/
# โœ… Reuses the destination path

History Search with Ctrl + R

The most powerful way to find a previous command.

How it works:

  1. Press Ctrl + R
  2. Start typing a keyword
  3. The most recent matching command appears
  4. Press Ctrl + R again to search further back
  5. Press Enter to run or โ†’ to edit

Example:

# Press Ctrl+R
(reverse-i-search)`git': git commit -m "fix: update readme"

# Press Ctrl+R again
(reverse-i-search)`git': git status

# Press Enter โ†’ runs "git status"
# Press โ†’ โ†’ exits search but keeps the command for editing
# Press Ctrl+C โ†’ cancels search

Navigation during search:

KeyAction
Ctrl + RSearch further back
Ctrl + JCopy command back to terminal
EnterExecute the found command
โ†’Exit search and edit
Ctrl + CCancel search
EscExit search (keep line)

Configuring History in ~/.bashrc

nano ~/.bashrc

HISTSIZE=1000
HISTFILESIZE=2000
HISTTIMEFORMAT='%d/%m/%y %T '
shopt -s histappend

source ~/.bashrc
SettingDescription
HISTSIZENumber of commands in memory (current session)
HISTFILESIZEMax size of the history file on disk
HISTTIMEFORMATTimestamp format for each command
shopt -s histappendAppend new commands instead of overwriting

Step-by-Step

1. Open the config file:

nano ~/.bashrc

2. Add the settings:

# ===== History Settings =====
HISTSIZE=1000                    # Keep 1000 commands in memory
HISTFILESIZE=2000                # Keep 2000 commands in file
HISTTIMEFORMAT='%d/%m/%y %T '    # Format: 15/01/24 10:30:45
shopt -s histappend              # Append, don't overwrite

3. Save and exit:

  • Ctrl + X โ†’ Y โ†’ Enter

4. Apply changes:

source ~/.bashrc

Result โ€” history with timestamps:

$ history 5
  501  15/01/24 10:25:30 ls -la
  502  15/01/24 10:26:12 cd projects
  503  15/01/24 10:26:45 git status
  504  15/01/24 10:27:03 git add .
  505  15/01/24 10:27:22 history 5

Other Useful History Settings

# Ignore duplicate commands
HISTCONTROL=ignoredups

# Ignore duplicates and commands starting with space
HISTCONTROL=ignoreboth

# Don't save specific commands
HISTIGNORE="ls:cd:pwd:exit:clear"

# Write to history immediately (not just on exit)
shopt -s histappend
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

# Combine history from multiple terminals
shopt -s histappend
PROMPT_COMMAND="history -n; history -a; $PROMPT_COMMAND"

HISTCONTROL values:

ValueMeaning
ignoredupsSkip consecutive duplicates
ignorespaceSkip commands starting with space
ignorebothBoth of the above
erasedupsRemove all previous duplicates

HISTIGNORE example:

HISTIGNORE="ls:cd:pwd:exit:clear:history"
# These commands won't clutter your history

Complete Example Session

# ============================================
# PART 1: VIEWING HISTORY
# ============================================

$ history
    1  pwd
    2  ls
    3  cd /var/log
    4  grep "ERROR" syslog
    5  cd ~
    6  history

$ history 3
    4  grep "ERROR" syslog
    5  cd ~
    6  history 3

$ history | less
# (scrollable)

$ history -c
$ history
    1  history

# ============================================
# PART 2: RERUNNING COMMANDS
# ============================================

# Last command
$ ls /var/log
...
$ !!
ls /var/log
...

# Add sudo
$ apt update
Permission denied
$ sudo !!
sudo apt update
# โœ… Success!

# By number
$ !5
cd ~

# By prefix
$ !git
git status

# By substring
$ !?log
cd /var/log

# Reuse last argument
$ mkdir my-project
$ cd !$
cd my-project

# ============================================
# PART 3: HISTORY SEARCH (Ctrl+R)
# ============================================

# Press Ctrl+R
(reverse-i-search)`ssh': ssh user@server

# Press Ctrl+R again
(reverse-i-search)`ssh': ssh-keygen -t rsa

# Press Enter โ†’ runs "ssh-keygen -t rsa"
# Or press โ†’ to edit

# ============================================
# PART 4: CONFIGURING HISTORY
# ============================================

$ nano ~/.bashrc

# Add at the end:
HISTSIZE=1000
HISTFILESIZE=2000
HISTTIMEFORMAT='%d/%m/%y %T '
HISTCONTROL=ignoreboth
HISTIGNORE="ls:cd:pwd:exit:clear:history"
shopt -s histappend

# Save: Ctrl+X, then Y, then Enter

$ source ~/.bashrc

# Verify changes
$ history 3
  501  15/01/24 10:30:00 git status
  502  15/01/24 10:30:15 vim app.js
  503  15/01/24 10:30:30 history 3

# ============================================
# PART 5: MULTIPLE TERMINALS
# ============================================

# In terminal 1:
$ echo "Terminal 1" >> test.txt

# In terminal 2 (with histappend and history -a):
$ echo "Terminal 2" >> test.txt
# Both commands appear in history when merged

# ============================================
# PART 6: PRACTICAL EXAMPLES
# ============================================

# Rerun a long command with sudo
$ iptables -L
Permission denied
$ sudo !!
sudo iptables -L
# โœ…

# Find and edit a previous command
# Ctrl+R โ†’ type "docker" โ†’ arrow right โ†’ edit โ†’ Enter

# Reuse an argument
$ cp report.txt /backup/reports/
$ cd !$
cd /backup/reports/

# Run command 42 from history
$ !42

# Run last command starting with "git"
$ !git

# Run last command containing "docker"
$ !?docker

Quick Reference

History Commands

CommandDescription
historyShow all history
history NShow last N commands
history | lessPaginated view
history -cClear current session
history -aAppend to history file
history -wWrite to history file

History Expansion

SyntaxMeaning
!!Last command
!NCommand at position N
!-NCommand N steps back
!stringLast command starting with string
!?stringLast command containing string
!$Last argument of previous command
!*All arguments of previous command

Configuration Variables

VariableDescription
HISTSIZEIn-memory history size
HISTFILESIZEHistory file size
HISTTIMEFORMATTimestamp format
HISTCONTROLDuplicate control
HISTIGNORECommands to ignore
histappendAppend mode

Best Practices

โœ… Do This:

# Use Ctrl+R for searching โ€” the most useful
Ctrl+R              # Then type keyword

# Use sudo !! for the "forgot sudo" case
$ apt update
Permission denied
$ sudo !!           # โœ… Instant fix

# Reuse last argument
$ mkdir project
$ cd !$             # โœ… Saves typing

# Configure history with timestamps
HISTTIMEFORMAT='%F %T '

# Ignore duplicates and space-prefixed
HISTCONTROL=ignoreboth

# Append instead of overwrite
shopt -s histappend

# Increase history size for power users
HISTSIZE=10000
HISTFILESIZE=20000

โŒ Don’t Do This:

# Don't use arrow keys to scroll forever
# โ†‘โ†‘โ†‘โ†‘โ†‘โ†‘โ†‘โ†‘โ†‘โ†‘      โŒ Slow
Ctrl+R              # โœ… Fast search

# Don't run !N without checking
$ !5                # โš ๏ธ What was command 5?
$ history 5         # โœ… Check first

# Don't ignore duplicates
# Default: history has 50 "ls" commands
HISTCONTROL=ignoredups    # โœ… Cleaner

# Don't forget to source after editing
nano ~/.bashrc
# ... add settings ...
source ~/.bashrc    # โœ… Apply changes

# Don't lose history between terminals
# Without histappend, last terminal wins
shopt -s histappend # โœ… All terminals append

Common Pitfalls

PitfallProblemSolution
!! runs wrong commandDangerous if last was rmCheck with history 1
History overwrittenMultiple terminals clashshopt -s histappend
Forgot to sourceChanges don’t applysource ~/.bashrc
No timestampsCan’t trace whenSet HISTTIMEFORMAT
Duplicate clutterSame command repeatedSet HISTCONTROL
Space-prefixed commands savedSensitive dataSet HISTCONTROL=ignoreboth

Real-World Use Cases

1. Forgot sudo โ€” Instant Fix

$ apt update
Permission denied
$ sudo !!
sudo apt update
# โœ…

2. Find and Rerun a Complex Command

# Press Ctrl+R โ†’ type "docker run"
(reverse-i-search)`docker run': docker run -p 8080:80 -v ~/data:/data nginx
# Enter โ†’ reruns it

3. Reuse a Directory Argument

$ cp report.pdf /home/kronos/Documents/2024/reports/
$ cd !$
cd /home/kronos/Documents/2024/reports/
# โœ…

4. Re-run Multiple Commands in Sequence

$ history 10
  ...
  495  docker stop myapp
  496  docker rm myapp
  497  docker build -t myapp .
  498  docker run -d -p 3000:3000 myapp

$ !495
!496
!497
!498
# โœ… Replays the whole sequence

5. Search History Across Sessions

# With histappend enabled
# Close terminal, open new one
$ history | grep docker
# โœ… Shows commands from previous session

6. Privacy โ€” Hide Sensitive Commands

# Start with space (if ignoreboth is set)
$  mysql -u root -pSecretPassword
# โœ… Not saved to history

# Or delete specific entries
$ history -d 501
# โœ… Removes entry 501

7. Multi-Terminal History Merging

# In ~/.bashrc:
shopt -s histappend
PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"

# Now both terminals share history instantly

Visual: How History Works

Session 1:                        ~/.bash_history:
  $ ls                              ls
  $ cd /var/log                     cd /var/log
  $ grep "ERROR" syslog             grep "ERROR" syslog
  $ exit                            (written on exit)

Session 2 (new terminal):
  $ history
    1  ls
    2  cd /var/log
    3  grep "ERROR" syslog
    # โœ… Loaded from history file!

WITHOUT histappend:
  Session 1 exits โ†’ writes to file
  Session 2 exits โ†’ OVERWRITES file
  Result: only Session 2's commands remain

WITH histappend:
  Session 1 exits โ†’ APPENDS to file
  Session 2 exits โ†’ APPENDS to file
  Result: both sessions' commands preserved

Summary

FeatureCommand
View historyhistory
Last N commandshistory N
Clear sessionhistory -c
Rerun last!!
Run command #N!N
By prefix!string
By substring!?string
Last argument!$
SearchCtrl + R
Configure~/.bashrc

Key takeaways:

  • History remembers your commands โ€” it’s the ultimate productivity tool
  • history shows the list โ€” pipe to less for paging
  • !! reruns the last command โ€” perfect for the “forgot sudo” case
  • !N, !string, and !?string rerun by number, prefix, or substring
  • !$ reuses the last argument โ€” huge time-saver
  • Ctrl + R is the fastest way to find a previous command
  • Configure in ~/.bashrc: HISTSIZE, HISTFILESIZE, HISTTIMEFORMAT, histappend
  • Always source ~/.bashrc after editing to apply changes
  • Use HISTCONTROL=ignoreboth to skip duplicates and space-prefixed commands

Remember: The three most important things you can do with history are: search it with Ctrl + R, rerun it with !! and !N, and configure it in ~/.bashrc with HISTTIMEFORMAT and shopt -s histappend. Get these three habits into your fingers and you’ll save hours every week. The terminal never forgets โ€” and neither should you!


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!