One of the ways to make yourelf more productive and to save unnecessary typing in the bash shell is to get familiar with navigating your history. There are a number of ways to navigate your bash history beyond simply using the up arrow to get at your last command. This is a quick reference to some of them.
The basics
Bash keeps track of your history in a file called (excitingly) .bash_history. You can have a look at your history quite easily $ history
If you are shy or want to cover your tracks, you can clear your history$ history -c
You can have your history ignore commands that start with a space HISTCONTROL=ignorespace
And you can also tell history not to record repeated commands with HISTCONTROL=ignoredups
To ignore duplicates and ignore commands with leading spaces, you can HISTCONTROL=ignoreboth
You can navigate through your history using the up and down arrow keys.
Exclamation marks (aka bangs)
The exclamation mark is commonly known as the "bang". It is a powerful piece of punctuation in the bash shell and, unlike when writing English, it is entirely appropriate to use it frequently.
The exclamation mark can be used to repeat commands or parameters and its behaviour can be modified in helpful ways. For example, I find printing the command rather than running it is quite useful.
Repeating commands
- Repeat last command
!!
- Repeat 110th command from history file
!110
- Repeat command from 3 lines ago
!-3
- Repeat last command that started "foo"
!foo
- Repeat last command that contained "bar" (add another question mark if you are going to type anything after "bar")
!?bar
Repeating command parameters
- All parameters from last command
!!*
- First parameter
!!^
- Last parameter
!!$
- Fifth parameter
!!:5
- Third to seventh parameters
!!:3-7
- Third to last parameters
!!:3-$
- Third to last parameters
!!:3*
Changing behaviour
- Print command, don’t run it
!!:p
- Run last command, changing first occurence of "foo" to "bar"
!!:s/foo/bar/
- Run last command, changing all occurences of "bar" to "baz"
!!:gs/bar/baz/
- Run last command but remove last part of file path (i.e. ls /home/user/.vimrc becomes /home/user)
!!:h
- Run last command but remove first part of file path (i.e. ls /home/user/.vimrc becomes .vimrc)
!!:t
- Grab first parameter of last command and taking the basename of the file (i.e. ls /home/user/mydoc.odt becomes /home/user/mydoc)
!!:1:r
Interactive searching, parameter shortcut
Sometimes you want to search your history in a more interactive way. You can use ctrl-r to do that. When you press it, bash begins searching your history for what you are typing. I use this all the time and think it is one of the nicest features in bash. You can use escape to get out of the search if bash is finding the wrong thing or something.$
(reverse-i-search)`l': ls -alh
You can grab the last parameter of the last command by pressing escape and full stop. You can grab the second parameter of the last command by esc 2, followed by esc ctrl-y. Catchy.