Back to home
3 min read

The Ultimate Bash History Expansion Guide

Bash bang commands are powerful shortcuts that allow you to reuse parts of your command history without retyping.


Bash "bang" commands are powerful shortcuts that allow you to reuse parts of your command history without retyping. These are officially known as History Expansions.


1. The Full Command: !!

The !! (bang-bang) shortcut represents the entire last command you ran.

Common Use Case: Forgot Sudo

If you run a command and get "Permission Denied":

apt update
# Result: Permission Denied

sudo !!
# Expands to: sudo apt update

2. Argument Designators

If you only want specific parts of the previous command (the arguments) and not the command itself:

The "Everything" Argument: !*

Grabs all arguments from the previous command, excluding the command name itself.

cp file1.txt file2.txt /backups/
ls -l !*
# Result: ls -l file1.txt file2.txt /backups/

The "Last" Argument: !$

Grabs only the very last word/path. This is the most popular shortcut.

mkdir /var/www/html/my_new_project
cd !$
# Result: cd /var/www/html/my_new_project

The "First" Argument: !^

Grabs only the first argument after the command.

diff original.py updated.py
vim !^
# Result: vim original.py

3. Granular Selection (The Colon : Index)

You can treat your previous command like an array, where the command is index 0.

Shortcut Description
!!:0 The command itself (e.g., git, ls, cd).
!!:1 The first argument.
!!:2 The second argument.
!!:2-4 A range of arguments (2nd, 3rd, and 4th).
!!:-2 From the first argument up to the second.

4. Searching History by Keyword

You don't just have to refer to the last command; you can go back further.

Execute by Name: !string

Executes the most recent command that starts with "string".

!docker
# Runs the last docker command you used (e.g., docker-compose up)

Search Within Command: !?string?

Executes the most recent command that contains "string" anywhere in the line.

!?logs?
# Might run: tail -f /var/log/syslog

Execute by Number: !n

Executes command number n from your history (type history to see the numbers).

!42
# Runs the 42nd command in your history list

5. Search and Replace: ^old^new

If you made a typo in a long command, you can quickly swap a string and re-run it.

cat /etc/config/servre.conf   # Typo: servre

^servre^server
# Result: cat /etc/config/server.conf

Note: This only replaces the first occurrence. For global replacement, use !!:gs/old/new/.


6. Safety First: The "Print Only" Modifier

If you aren't sure what an expansion will do and don't want to accidentally delete something, append :p to the end.

!rm:p
# Bash prints the command but does NOT execute it
# It also adds it to history so you can press Up + Enter to run it

Pro Tip: The "Alt + ." Shortcut

In most modern terminals (like iTerm2, GNOME Terminal, or VS Code), holding Alt and tapping period (.) will cycle through the last arguments of your previous commands directly in your prompt. It is often faster and safer than using !$.