In a previous post I discussed bash emacs mode—a convenient way to get around the bash command line quicker. Taking the time to learn these commands definitely yields a welcome boost to productivity. (And if you cannot remember them at first there is a bash cheat sheet.)
I recently learned a few things about bash history that’s made me more productive on the command line, so I thought I would share.
Searching Bash History
Almost anyone who has spent any time at all on the command line will know that you can move backwards and forwards through the history of previous commands with the up and down arrow. Suppose, however, you want to rerun a previous command issued several command lines before. You could bang away at the up arrow. But this is tedious and error prone—you can easily overshoot the target command line.
Fortunately there’s a better way. Bash allows you to search backwards through your history with ⌃R. After typing ⌃R begin typing the string that you are searching for and the bash shell will return the most recent matching string. To search further back in your history for other matches hit ⌃R as many times as necessary. Nice.
Old School
The bash history predates the emergence of arrows on keyboards. So there are ways to move through bash history with these. Thus:
!!
takes you to the previous command line. What’s the point, you might wonder? Why bother to use three keystrokes when one (up arrow) will do? Well, you can use !! with other elements of a command line:
$ tree
-bash: tree: command not found
$ ~/bin/!!
~/bin/tree
Nothing similar can be accomplished with the up arrow.
The bash history is a numbered list of command lines issued to the shell. You can select a particular command line using !n where n is the number of the command.
One of the most useful commands for traversing bash history is !$ which gives the last argument of the previous command:
$ mkdir -p myproject/src
$ cd !$
$ PWD
/Users/markelikalderon/myproject/src
Another useful command is !* which gives all of the previous commands. This can be useful for correcting (sadly inevitable) typing errors:
$ sbn commit -m "Initial commit"
bash: sbn: command not found
$ svn !*
svn commit -m "Initial commit"
Another way of dealing with this typo is to use a quick substitution with the caret ^.
$ sbn commit -m "Initial commit"
-bash: sbn: command not found
$ ^sbn^svn
svn commit -m "Initial commit"
There’s more, much more, that can help you traverse the command line efficiently. As ever, RTFM, baby.
Update: There is more on bash history on the TextMate Blog.
{ 2 } Comments
The last argument can also be accessed with Esc-. (escape, then period–not at the same time). Repeating the Esc-. sequence moves you back to earlier arguments; it’s like the uparrow key, but for arguments only.
Real Emacs users will refer to this as Meta-. and you may see references to the Meta key in bash literature. But since no key on the Mac maps to Meta, the Escape key works fine. For example, Esc-b moves you back one work on the command line, Esc-f moves one word forward.
I didn’t know about !*–I’ll try to commit it to memory.
Thanks Dr Drang!
If you like !*, there is also !some_string, that executes the last command that begins with some_string. That can be dangerous, so there is also !some_string:p that will print the last command that begins with some_string.
Post a Comment