I’ve had a lot of fun recently posting about how to do stuff on the command line in Linux. My focus is specifically for Ubuntu users, but the information and techniques can be used for any Linux distro.
Since I’m probably going to end up with a lot of content under this topic, I’ve decided to create a dedicated tag: Mastering the Command Line. I’ve gone through my older posts on this topic and tagged them as well. So, make sure to check out Mastering the Command Line if you want to know how to become a command line power user.
Back to today’s topic. You’re starting to learn how to use the command line, but it’s annoying to always have to type in similar commands over and over. If only there were a way to pull up commands that you’ve already run to run again as is or to quickly modify. Today, I’m going to teach you how to do exactly this.
Introduction to BASH Command Line History
BASH (Bourne Again SHell) is the default command line shell that is used in Ubuntu, and most other distros for that matter. The instructions that I give here are specific to BASH and may or may not work in other shells. Since most people don’t modify which shell they access through Terminal, I only point this out to inform those who have changed their shell that their experiences may differ depending on the shell used.
When you close a Terminal session, BASH writes all the commands you’ve run for that session to your
~/.bash_history file. When you load a new session, this file is read and those commands along with the new commands you execute for that session become your new command history.
It’s important to keep in mind that commands executed for a session are only written when you exit. If you have two sessions running concurrently, they cannot cross-reference the newly-executed commands run in the other session. Furthermore, if you force a Terminal session to quit, the command history will not be updated.
Simple Command History Navigation
The easy way to get started with your command history is to simply navigate with the up and down arrow keys. Using the up key, you can scroll through previous commands one command at a time. To scroll back down the list, you can use the down arrow key.
Once you’ve found the desired command, you can treat it as if you’ve typed that command in the command line. You can simply press Enter to execute the command again, or you can modify the command as needed before executing it.
This method is very good for quickly running commands that you have to execute repeatedly without many other commands between.
Listing and Searching Command History
BASH provides the
history command that when executed with no options will list the entire command history. Each command will be preceded with a number that represents that command’s command number. I’ll tell you how to use these numbers below.
You can also have the
history command produce just the last certain number of commands by supplying a number. For example, if you want to see the previous ten commands, you can run the following:
[user@local ~]$ history 10 510 which bash 511 echo $$ 512 ps aux|grep 32115 513 which sh 514 history 515 man history 516 history|grep echo 517 vi ~/.bash_history 518 tail -10 ~/.bash_history 519 history 10 [user@local ~]$
Notice that the last command is the same as the command you ran to produce it. So, “
history 1” will just show you “
[command number] history 1“.
If you remember that you ran a really cool command and can’t quite remember how you did it, combining history with grep provides an easy way to find that command with just a piece of the command.
For example, let’s say that I ran a command that listed all the files that end in “
.php” inside the
~/wordpress folder it then filters for just matches that contain the text “
link” and then reverses the output. I was quite proud of that command, but I can’t remember how I did it. So, I search through my history.
Since I don’t think that I have the word “
link” in many of my commands, I pick it as the target to search for and run the following:
[user@local ~]$ history | grep link 412 find ~/wordpress -type f | grep \.php$ | grep link | sort -r [user@local ~]$
That’s what I was looking for. Now I can bask in the glory of my ingenious command and use it as the inspiration for other inspired words of command line magic.
Running Previous Commands Again
Searching through the history is great and all, but I’d rather not have to copy and paste found commands. I’d like to just run them immediately. BASH to the rescue again.
If you’d like to run the previous command again quickly, you can simply run “
!!“. The first exclamation point tells BASH that you are running a previous commands. The second exclamation point tells BASH that it’s the last command that you’d like to run again. It’s a double exclamation point simply to make it quick and easy to type in.
I’ve already shown you how to look through your history and find a specific command in your history complete with the command number. Now is the time to make use of that number. If I wanted to execute command number 510 (
which bash) again using the history, I can simply run the following:
[user@local ~]$ !510 which bash /bin/bash [user@local ~]$
Notice how running the command again first lists the actual command and then the output.
BASH substitutes the
!number command with the actual command from the history. This allows you to supply additional parameters to the command. The following is a silly example, but it gets the point across.
[user@local ~]$ !510 dash which bash dash /bin/bash /bin/dash [user@local ~]$
Notice how the command now has the additional parameter added to the original command. As expected, the full command is listed followed by the command output.
You can also do the standard manipulations such as piping the output, “
!412 | grep wp-admin“, or redirecting the output, “
!510 > shell_locations.txt“.
Searching and Running Previous Commands
!” functionality of BASH also allows you to search through the history and execute the first match.
The basic form of this simply searches for matches at the beginning of the command. “
!find” executes the most recent command that begins with “
You can also search the entire command for a match. “
!?link?” executes the most recent command that contains “
Advanced History with Regular Expressions
As with many tools in the Linux world, you can attain great power by combining the tool with regular expressions. The history in BASH allows you to run previous commands with a search and replace in Regex fashion.
Let’s take my searching through the
~/wordpress example, command number 412, and run it again with some modifications. This time, instead of searching
~/wordpress, I’d like to search through
/home/site/public_hmtl/wordpress. I’d do that with the following:
[user@local ~]$ !412:s|~/wordpress|/home/site/public_html/wordpress| find /home/site/public_html/wordpress -type f | grep \.php$ | grep link | sort -r /home/site/public_html/wordpress/wp-links-opml.php /home/site/public_html/wordpress/wp-includes/link-template.php /home/site/public_html/wordpress/wp-admin/update-links.php /home/site/public_html/wordpress/wp-admin/options-permalink.php /home/site/public_html/wordpress/wp-admin/link.php /home/site/public_html/wordpress/wp-admin/link-parse-opml.php /home/site/public_html/wordpress/wp-admin/link-manager.php /home/site/public_html/wordpress/wp-admin/link-category.php /home/site/public_html/wordpress/wp-admin/link-add.php /home/site/public_html/wordpress/wp-admin/edit-link-form.php /home/site/public_html/wordpress/wp-admin/edit-link-category-form.php /home/site/public_html/wordpress/wp-admin/edit-link-categories.php [user@local ~]$
Note that the search and replace is done by adding “
:s|find|replace|” to the end of the
history command. I used the pipes,”
|“, to deliminate the find and replace portions to make it easier to add the forward slashes, “
/“, to the terms. You can also use “
I hope that you enjoy my Mastering the Command Line series. If you have any command line-specific requests, please leave a comment, and I will see about creating a tutorial on that topic.
Remember, those who forget
history, are doomed to repeat it by manual entry.
Did I help you? Send me a tip.