Bash History

Recently I’ve discovered some useful history shortcuts for use with bash. I’ve known for a long time that !! expands to the previous command. I’ve mostly used this for prepending sudo to a command that I didn’t realise needed heightened priveleges for. A trivial example:

$ apt-get update
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
$ sudo !!
sudo apt-get update
Hit http://security.ubuntu.com raring-security Release.gpg
Hit http://extras.ubuntu.com raring Release.gpg
...etc.

There are some other very useful history expansions that I’ve only recently stumbled across:

  • !^ becomes the first argument of the previous command
  • !$ becomes the last argument of the previous command
  • !* becomes all arguments of the previous command, except for the zeroth.

Some examples:

$ echo one two three
one two three
$ echo !^
echo one
one
$ echo one two three
one two three
$ echo !$
echo three
three
$ echo one two three
one two three
$ echo !*
echo one two three
one two three
$ echo one two three
one two three
$ echo !!
echo echo one two three
echo one two three

Very convenient. The one I’ve found myself using the most is !^, as in:

$ ls *.test
01.test  02.test  03.test  04.test  05.test
$ rm !^
rm *.test

But wait, there’s more!

I don’t really use the following very often, but I’ll put them here for completeness:

  • !-n calls the nth most recent command; !! is a special case, equivalent to !-1
  • Word designators: !-n:x calls the xth argument of the nth most recent command. !-2:2 would call the second argument of the second most recent command; !-2:0 calls the zeroth argument (in the examples given above, that would be echo)
    • !-n:^, !-n:$ and !-n:* all work as you would expect
    • Ranges work; !-n:2-5 expands to the second, third, fourth and fifth arguments of the nth most recent command, and !-n:3-$ will expand to the third through to the last arguments of the nth most recent command
  • !string expands to the most recent command starting with string; it can use word designators as above
  • String substitution can be accomplished by putting :s/old/new on the end (after any word designators), which will find the first instance of old and replace it with new.

How did I discover this?

I was trying to use !!, and accidently typed !1 – which expanded to sudo apt-get shutdown -h. It turns out that that was the first command listed in my bash history; you can see a complete list of your history with

history

This is grep-able:

$ history | grep shutdown
    1  sudo shutdown -h now
   92  sudo shutdown -r now
  120  sudo shutdown -r now
  130  sudo shutdown -r now
  131  man shutdown
...etc.

So you see, !1 expands to the first command in my history. This can use word designators and substitution; for example:

$ !1:s/-h/-r
sudo shutdown -r now

…obviously, in this case I could just use !92, as you can see from my history.

For a lot more information, see man history or (even better) info history.

Advertisements

Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: