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
“.
Searching History
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
The “!
” 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 “find
“.
You can also search the entire command for a match. “!?link?
” executes the most recent command that contains “link
“.
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 “:s/find/replace/
“.
Closing Thoughts
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?
Thanks for the quick tutorial on how to use history in Bash! Would you believe that after all this time, I didn’t know that secret ‘!’ + search term shortcut? :\ Some of the most obvious things escape the most seasoned pros sometimes.
I can easily believe it. I find out something new every day.
i didn’t know about that either, and i too probably should have by now! v. handy – thanks!
This is fantastic!! I’ve seen this a major drawback of having switched to Linux – always using that up arrow to try to find the command I want to repeat, or partially use. This will save me an good amount of time and an enormous headache.
> Chris Jean
> Copyright © 2012 All Rights Reserved
Do you allow me to translate this article to Persian? (Surely all rights of the author will be regarded and a permanent link will be referred to this page)
I’ve been meaning to update the license on this site for quite a while now.
The site’s post content is now declared public domain under the CC0 1.0 Universal license. Feel free to use it in any manner you see fit.
Thanks for the interest and the reminder to update the license.
I appreciate your consideration 🙂
I’ve already replaced the translation on this post: Ctrl+F > search for Jean. According to the license permissions, I made some changes into the examples of the text to clarify them for newbies! and also the “I” (active voice) has converted to “Passive Voice”.
> I believe that the free flow of information and ideas is key to the past and future development of mankind.
> Thus, the post content on this site is declared public domain (CC0 1.0 Universal)
Great! though I’m keen on GNU FDL (because of copyleft), but CC (with/without ‘by’ and/or ‘sa’) is an another great choice.
Thanks for that Hadron.
I considered using a copyleft license, but I opted for a more liberal license as I truely don’t care if attribution is given or not. If the information I write is beneficial, I don’t want to tie it down to any license constraints.
Hey!
Really interesting : )
I was wondering if you know a way to show the history *without* the line numbers at the beggining, so I can simple store some command sequence (without having to clean the numbers on the front each time).
Thanks in advance!
Sorry for the late reply rho. While the
history
command itself doesn’t support the ability to remove line numbers, piping the output throughsed
with a search/replace regex allows you to get a clean listing without the line numbers. For example:In Linux 2.6.32.220, if you modify command history, and modify the line without pressing , and then press the or arrow, then the modified history is saved. If use the and keys to move to another matching line, then the modified history is not saved. This is not consistent.
Thanks.
ZQY
It looks like portions of your comment were eaten, so I’m not quite sure what you are saying or if you are asking a question.
No sabia que existia un mecanismo adicional para acceder a la historia. Menos aun que era tan poderoso.
Gracias.
Hi Chris,
Maybe you would like to add to this article? With Ctrl+R you can search the history.
Press Ctrl+R, type “link” and the command line will give you the first, from the bottom of the history, match with “link” in it.
Keep pressing Ctrl+R and it will traverse your history!
Have a great day!
A great tip, Alexandre!
The `history` is very useful, `!` is better and easier, but CTRL+R is even better!
i connected to a linux server using putty and in that i gave some commands n i have forget them. now i want to get those commands. can i be able to get thyem ??
Depending on how long ago that was and how the server is configured, possibly. If the server’s shell is bash, the user’s home folder should have a .bash_history file that contains a listing of recent commands.
This is awesome, helped me alot. Thanks!
Win!
very helpful thanks !!
Learn something new every day. I always just used arrow up and down to scroll through recent command line entries but wow …… “history 25” is like a god send. Thanks for a very good write up on bash history.
thanks for the useful tips and made to well presented and easy to read! Cheers
Hey Chris,
How can I ERASE all the commands I previously used from the command line history ????
Thanks.
The commands are typically logged to the
.bash_history
file in the user’s home directory. If you delete the file, you delete the command history. The file will come back however in order to keep track of new commands.