How to use the command "history expansion" (with examples)
History expansion is a feature in various Unix-like shells, such as sh
, bash
, zsh
, rbash
, and ksh
, that allows users to reuse and expand their command history. It provides a convenient way to recall and modify previously executed commands. This article will demonstrate several use cases of history expansion with examples.
Use case 1: Run the previous command as root
Code:
sudo !!
Motivation: This use case is helpful when a user forgets to run a command with administrative privileges. Instead of retyping the entire command with sudo
, they can use history expansion to quickly run the previous command as root.
Explanation:
sudo
: The command to execute the subsequent command with elevated privileges.!!
: A history expansion expression that is replaced by the previous command.
Example output:
If the previous command was apt-get upgrade
, running sudo !!
would execute:
sudo apt-get upgrade
Use case 2: Run a command with the last argument of the previous command
Code:
command !$
Motivation: When the last argument of a previous command needs to be used as an argument for a different command, history expansion can save time by automatically inserting the last argument in the new command.
Explanation:
command
: The subsequent command to be executed with the last argument of the previous command.!$
: A history expansion expression that represents the last argument of the previous command.
Example output:
If the previous command was mv file.txt folder/
, running command !$
would execute:
command folder/
Use case 3: Run a command with the first argument of the previous command
Code:
command !^
Motivation: Sometimes, only the first argument of a previous command needs to be reused. By utilizing history expansion, users can easily embed the first argument of the previous command in a new command.
Explanation:
command
: The subsequent command to be executed with the first argument of the previous command.!^
: A history expansion expression that represents the first argument of the previous command.
Example output:
If the previous command was wget https://example.com/file.zip
, running command !^
would execute:
command wget
Use case 4: Run the Nth command of the history
Code:
!n
Motivation: To quickly retrieve and execute a specific command from the history, users can use this history expansion syntax instead of scrolling through their entire history to find the desired command.
Explanation:
n
: The command history number to be executed.
Example output:
Assuming the command with history number 5
was ls -l
, running !5
would execute:
ls -l
Use case 5: Run the command n
lines back in the history
Code:
!-n
Motivation: When examining previous commands, users occasionally find it necessary to run a command that was executed a specific number of lines back in their history. This history expansion expression allows them to quickly execute the desired command without copying and pasting.
Explanation:
-n
: The number of lines back in the history from which to retrieve and execute the command.
Example output:
Assuming the current command is on line 10
of the history and the command on line 7
is git status
, running !-3
would execute:
git status
Use case 6: Run the most recent command containing string
Code:
!?string?
Motivation: Finding and executing the most recent command that includes a specific keyword or substring can be tedious when manually searching through the history. By using this history expansion syntax, users can effortlessly rerun the most recent command containing the desired string
.
Explanation:
string
: The keyword or substring to search for within the command history.?
: Delimiters to encapsulate thestring
.
Example output:
Considering the most recent command containing the word search
is grep -r search .
, running !?search?
would execute:
grep -r search .
Use case 7: Run the previous command, replacing string1
with string2
Code:
^string1^string2^
Motivation: In situations where only a small modification is required in the previously executed command, manually retyping the entire command would be inefficient. By using the history expansion syntax ^string1^string2^
, users can easily substitute string1
with string2
and rerun the modified command.
Explanation:
string1
: The substring to be replaced in the previous command.string2
: The replacement forstring1
.
Example output:
Assuming the previous command was echo Hello, world!
, running ^Hello^Hi^
would execute:
echo Hi, world!
Use case 8: Perform a history expansion, but print the command that would be run instead of actually running it
Code:
!-n:p
Motivation: For scenarios where users want to inspect the command resulting from a history expansion before executing it, appending :p
to the history expansion expression enables previewing the command without actual execution.
Explanation:
-n
: The number of lines back in the history to retrieve for history expansion.:p
: A modifier that instructs the shell to print the command instead of executing it.
Example output:
Considering the command on line 7
of the history is ls -a
, running !-3:p
would output:
ls -a
Conclusion:
History expansion is a powerful feature that enhances command line productivity by allowing users to easily reuse and modify previously executed commands. With the various forms of history expansion covered in this article, users can optimize their command line workflow, saving time and effort. By mastering these history expansion techniques, users can efficiently recall and manipulate their command history to meet their specific needs.