In Bash, the history
command is the key to not just understanding what you've been doing during your shell session, but also to raw material for new commands you want to run in the future. History
is especially useful when you're running a headless server. If you have no mouse, you can't easily copy and paste the last half of a complex command to run a slightly modified version of it, so you have to type the whole thing over again - unless you use history
modifiers.
Keep history out of your history
Before discussing history, here's a tip for keeping literal history
entries out of your history.
The problem with using the history
command to review your history
is that it adds an entry to your history
file. These entries not only clutter up your history
, but they also cause each line to regress "farther" away from your current position.
$ cd example-project
$ ls
bin doc src
$ touch doc/LICENSE
$ history
102 cd example-project
103 ls
104 touch doc/LICENSE
105 history
$
A moving target is tough to track and hard to hit, so if you plan on seriously using your history
to speed up your Bash interactions, add this configuration to your .bashrc
file:
export HISTCONTROL=$HISTCONTROL:ignorespace
This configuration prevents any command preceded by a space from being added to your Bash history
.
$ cd example-project
$ ls
bin doc src
$ touch doc/LICENSE
$ history
102 cd example-project
103 ls
104 touch doc/LICENSE
$
[ Free online course: Red Hat Enterprise Linux technical overview. ]
History events
The basic structure of shell history
starts with a list of events
. An event
is anything you've entered into the shell, followed by the Return
or Enter
key. Each event
is assigned an index number (a line number), and you can view and recall events by using event designators
.
For instance, to recall a specific line item in your shell history
, use an exclamation point (!
) followed immediately by the number of the history
line:
$ history
102 cd example-project
103 ls
104 touch README
$ !103
ls
bin doc README src
You can also refer to past commands relative to their position in the history
listing. For example, to run a command two lines in the past, think of your current prompt as one greater than the last line in history
, and then subtract the number of the line you want to execute from your current line number. In this example, line 103 is the target line and 105 is the current prompt (for a delta of 105-103=2):
$ history
102 cd example-project
103 ls
104 touch README
$ !103
ls
bin doc README src
You can save a whole character if you just want to re-run the last line. The expression !!
and !-1
are synonymous:
$ history
102 cd example-project
103 ls
104 touch README
$ !103
ls
bin doc README src
Notice the command itself is repeated in the output when history
is repeated. For brevity and clarity, such output is excluded from the remaining examples in this article.
Word designators
Bash has features to help you parse through your history
using word designators
, and tools to allow you to modify the commands in your history
. It might help to think of your shell history
as an indexed array, or even as a large history object consisting of lots of smaller items. Each word on each line of your history
is indexed, starting at 0 (which is usually the command, but multi-part commands and environment variable prefixes are notable exceptions). You can access each index by adding a colon (:
) to your line reference, followed immediately by the word designator
.
Here's an example accessing the first word:
$ history
102 cd example-project
103 ls
104 touch README
$ !103
ls
bin doc README src
Because grabbing the first argument is common, the circumflex (or the "hat": ^
) is an alias for :1
.
$ echo foo
$ !!^
foo
On the other end of the spectrum, the dollar ($
) sign represents the final argument:
$ echo foo bar baz
$ echo !!$
baz
Ranges of words
You don't have to settle for just one argument. You can extract ranges of an index, too. All arguments but the zeroth is available with an asterisk (*
).
$ echo foo bar baz
$ touch !!*
$ ls
foo bar baz
This is actually a synonym for 1-$
(that is, the first argument to the last argument). As you might expect, you can arbitrarily define your range using this unabbreviated notation. This example references the second to fifth arguments, ignoring the first and final two arguments:
$ cp foo a.sh spacer.sh rev.bin sync.py baz ~/dest
$ cd ~/dest
$ chmod ug+x !-2:2-5
$ ls -l --classify
a.sh* baz foo rev.bin* spacer.sh* sync.py*
If you just need to exclude the final single word in an index, you can provide a range with no termination:
$ cp foo a.sh spacer.sh ~/dest
$ cd ~/dest
$ chmod ug+x !-2:2-
$ ls -l --classify
a.sh* foo spacer.sh*
Using history for speed and precision
The history
command isn't always about reducing key presses. You can use your Bash history
to avoid accidentally excluding a file or folder from an important operation, or misspelling a filename. Get comfortable with the history
command for more robust Bash interactions.
[ Want to try out Red Hat Enterprise Linux? Download it now for free. ]
About the author
Seth Kenlon is a Linux geek, open source enthusiast, free culture advocate, and tabletop gamer. Between gigs in the film industry and the tech industry (not necessarily exclusive of one another), he likes to design games and hack on code (also not necessarily exclusive of one another).
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Original shows
Entertaining stories from the makers and leaders in enterprise tech
Products
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Cloud services
- See all products
Tools
- Training and certification
- My account
- Customer support
- Developer resources
- Find a partner
- Red Hat Ecosystem Catalog
- Red Hat value calculator
- Documentation
Try, buy, & sell
Communicate
About Red Hat
We’re the world’s leading provider of enterprise open source solutions—including Linux, cloud, container, and Kubernetes. We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.
Select a language
Red Hat legal and privacy links
- About Red Hat
- Jobs
- Events
- Locations
- Contact Red Hat
- Red Hat Blog
- Diversity, equity, and inclusion
- Cool Stuff Store
- Red Hat Summit