Bash History Expansion and Prompt Magic
Contents
Interesting and useful use cases of !, #, and ? expansions in Bash
I love to always learn new Linux shell commands and wrangling moves. This recent days I learned a few useful command line “tricks” that I’ve never seen anyone using so I thought of sharing them.
They all cover the special characters and escape sequences related to history expansion and prompt customization. This post will:
- Clarify the real tools behind
!,#, and?in Bash. - Walk through practical examples you can copy and adapt.
- Challenge assumptions by revealing lesser-known tricks.
- Deliver actionable steps to integrate these shortcuts into your workflow.
[!INFO] Some of this “chops” are not as intuitive so I guess it’s a matter of practicing a few at a time so eventually they become second nature. I’ve found that when we’re working on the command line, we do sub-second operations that rely 100% on muscle memory and intuition, so it’s useful to learn this “tricks” before we ever need them so they’re there in our memory when we actually do.
Bash History Expansion (!)
Bash’s history expansion allows you to recall and re-execute commands from your session’s history.
!!— Repeat the entire last command.
This may be the most commonly needed one: when we forgot to use sudo and need to run our command again…
$ sudo !! # run the previous command with sudo
-
!n— Execute command number n fromhistory.$ history # get list 42 ls 43 pwd 44 echo hello $ !43 # runs `pwd` -
!-n— Run the command n lines back.$ !-2 # repeat the command two steps ago -
!string— Execute the most recent command starting withstring.$ !ec # runs `echo hello` if that was the last matching -
!?string?— Execute the most recent command containingstring.$ history 50 ls /var/log 51 cat /var/log/syslog 52 echo done $ !?syslog? # runs `cat /var/log/syslog` -
Word designators — Extract portions of the previous command:
!:0— The command itself (e.g.cat).!:1— First argument (e.g./var/log/syslog).!:n— nth argument.!$— Last argument (same as!: -1).!^— First argument (!:1).!mkdir:$— “Fetch” lastmkdircommand in our history, and “reuse” its argument (See example below)
For example, having written a command with a large argument, and wanting to reuse it with other command:
- Here, we “reuse” mkdir argument, which we don’t want to write again, and just append “README.md” to create a file there:

Since we cannot simply use !$ because mkdir is not our last command anymore, we can “fetch” it from our history and “reuse” its argument:

That’s it for this quick recap. Those new “chops” are very useful for those long work sessions on the terminal and can save us some precious time with tedious commands.