Skip to main content
  1. Argv.Blog/

Bash History Expansion and Prompt Magic

471 words·3 mins·
Linux Scripting Programming Terminal Bash Shell
Table of Contents
Linux - This article is part of a series.
Part : This Article

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:

  1. Clarify the real tools behind !, #, and ? in Bash.
  2. Walk through practical examples you can copy and adapt.
  3. Challenge assumptions by revealing lesser-known tricks.
  4. 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 from history.

    $ 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 with string.

    $ !ec             # runs `echo hello` if that was the last matching
    
  • !?string? — Execute the most recent command containing string.

    $ 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” last mkdir command 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:

Chop1

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

Chop1


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.

J Armando G
Author
J Armando G
Cybersecurity & General Tech Enthusiast
Linux - This article is part of a series.
Part : This Article