Bash hotkeys

Do you know Ctrl-r, Ctrl-w, !! or Alt-.? Here's why you should.

Sometimes Linux commands can be repetitive. For instance, let's create a new directory and cd into it:

mkdir something
cd something

Or, search for a package name, and after we found out that it's listed under exactly that name, install it:

apt-cache search python-django
apt-get install python-django

Or, install and run htop:

apt-get install htop
htop

This obviously sucks. Is there an easier way?

Alt-.

What if I told you there's a hotkey that rids you of typing that stuff twice? That hotkey is Alt-. (Alt + period).

Type the following in bash:

echo hello
echo <press alt-.>

Bash will autocomplete the second line to:

echo hello

So, applied to the examples from above:

mkdir something
cd <alt-.>
apt-cache search python-django
apt-get install <alt-.> htop
<alt-.>

Hitting Alt-. multiple times will iterate further through the history and fetch things from older command lines.

Ctrl-r

While we're at it, wouldn't it be great if we could fetch a command from the history that we executed a while back, but we're not quite sure how exactly we spelled it? Have you ever caught yourself running history | grep something, only to then copy-paste whatever command line you found into the actual command line to run it? There's gotta be a better way!

Actually, there is: If you hit ctrl-r, bash will replace the prompt with this one:

(reverse-i-search)`':

You can now enter a search term, and bash will substitute the last command you ran that matches the term:

(reverse-i-search)`install': apt-get install htop

Now you just hit enter and the command is run.

But what if you don't find the correct replacement and need to search the history for earlier occurrences? Easy: you just hit ctrl-r again, until you found what you're after. If nothing matches, hit ctrl-c to cancel.

Ctrl-w

This one deletes the last word from the current command line. So suppose you ctrl-r'ed yourself this command line:

apt-get install iftop htop iotop systtat

Now if you want to delete the last two words, you can of course use backspace and make sure you don't delete too far. Or you just type ctrl-w twice.

!!

I sometimes want to check if the file implementing a certain command is a script, and if so, edit it. This usually amounts to:

# which django-admin           # is it installed? where's it stored?
/usr/bin/django-admin
# file /usr/bin/django-admin   # what is it?
/usr/bin/django-admin: POSIX shell script, ASCII text executable
# vi /usr/bin/django-admin     # hooray, text-based! let's edit

Considering that the file line uses the output from the which command, it can also be written as:

# file `which django-admin`

And bash has this nifty little thingy that replaces an occurrence of !! with the last commandline you ran, so you can type that as:

# which django-admin
/usr/bin/django-admin
# file `!!`

Bash will now expand the second command to:

# file `which django-admin`

But wait, there's more! In order to now run the vi command without having to type the same thing again, you can now go:

# vi <alt-.>

And bash will complete that line to:

# vi `which django-admin`

(And do go read this thing if you're on a Debian system. It's a work of art.)