Command-line history
Part of an ongoing series of essays tentatively entitled Don’t embarrass me, Don’t embarrass yourself: Notes on thinking in C and Unix.
Good Unix programmers (or perhaps all Unix users) regularly interact
with the operating system through an interactive shell
, through which
you type commands. There are a variety of shells, but many Unices [1]
ship with a default of bash, the Bourne-again shell [2]. One nice thing
about bash, and most other shells, is that it keeps a history of the
commands you’ve typed, so that you can see what you’ve done in the past
and do it again [3].
A frequent use of history is to repeat the last command you just typed,
or to do a quick variant of the last command you just typed. To execute
the command you just typed, you need only write !!
. For example, when
I’m lazy and I’ve forgotten the appropriate flags for doing multiple
copies, I often write something like the following.
$ lpr cnix-command-line-history.ps -P duerer
$ !!
lpr cnix-command-line-history.ps -P duerer
That last line is the shell telling me what it substituted for me. Another
use of !!
is when you realize that you should have executed the prior command
with different permissions.
$ install eni /usr/local/bin
install: cannot create regular file '/usr/local/bin/eni': Permission denied
$ /usr/bin/sudo !!
/usr/bin/sudo install eni /usr/local/bin
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for username:
For those of you don’t know, sudo
allows you to execute commands as the
root user [5].
Sometimes we want to repeat an earlier command. Fortunately, bash history
provides some nice mechanisms for that, too. If you follow the !
with
one or more letters, bash repeats the most recent command that started
with those letters.
$ pwd
/home/rebelsky/Web/musings
$ !l
lpr cnix-command-line-history.md -P duerer
$ ls
cnix-command-line-history.html
cnix-command-line-history.md
cnix-command-line-history.ps
$ !l
ls
cnix-command-line-history.html
cnix-command-line-history.md
cnix-command-line-history.ps
$ !lp
lpr cnix-command-line-history.md -P duerer
Of course, not all of us remember our recent commands, so the shell provides
a convenient history
command to tell you what you’ve been up to [6].
$ history | tail -8
525 html2ps < cnix-command-line-history.html > cnix-command-line-history.ps
526 lpr cnix-command-line-history.ps
527 pwd
528 ls -l
529 vi cnix-command-line-history.md
530 jobs
531 history
532 history | tail -8
As this suggests, your commands are numbered [7]. You can also use !
[8]
notation to refer to commands by number.
$ !526
lpr cnix-command-line-history.ps
Finally, you can refer to the last element of the previous command using
!$
[9]. Here’s a variant of one example in which I used !$
.
$ !ht
html2ps < cnix-command-line-history.html > cnix-command-line-history.ps
-bash: cnix-command-line-history.ps: cannot overwrite existing file
$ rm !$
rm cnix-command-line-history.ps
$ !h
html2ps < cnix-command-line-history.html > cnix-command-line-history.ps
Is that all that you can do with the command-line history? Certainly not.
If you mistype a letter (or more) in the previous command, you can do a
quick substitution using the ^
symbol
$ lpr -p duerer cnix-command-line-history.ps
lpr: Error - unable to access "duerer" - No such file or directory
$ ^-p^-P
lpr -P duerer cnix-command-line-history.ps
In case you couldn’t tell, we write a caret, the text to replace, another caret, and the replacement.
All of these fun history commands were created in the early days of
Unix, before we had fancy displays, or perhaps even displays at all [14].
Now we have much fancier displays [15] with addressable cursors and everything.
And with the fancier displays come other ways of dealing with your history.
For many, the easiest way to browse and use your history is with the arrow keys. The up-arrow key brings you backwards in your history. If you’ve gone too far back, the down-arrow key brings you forward [17]. Once you’ve found a command you like, you can edit it with the arrow keys, the delete key, and, well, any character you’d like to type.
You can also search backwards through commands with Ctrl-r. I will admit that I rarely, if ever, use that facility.
In fact, although I regularly access history through the arrow keys, I most
regularly use the old-fashioned bang commands
. I’m fast with them, and they
help me get the job done.
I’d recommend that you practice with the various approaches, and see which one works for you. Perhaps the most important thing is knowing that you have a history, and that you can use it [18].
Summary:
!!
(bang bang
) - repeat the last command!$
(bang dollar
orbang bucks
) - the last part of the last command!5
(bang five
) - repeat command five
[1] I believe that the plural of Unix is Unices
. You can form
plurals in your own way. Strangely, the jargon file entry for
Unix does not provide
a plural.
[2] Stupid puns is a hallmark of Unix tools. One of the earlier shells
was the Bourne shell (sh
), so named because it was written by Stephen
Bourne. An updated version of it therefore got this name.
[3] My software design students know that they should keep their code
DRY
, as in Don’t Repeat Yourself
. However, it turns out that we
often need to rerun commands, in different contexts
[4] In case you weren’t sure, !!
is pronounced bang bang
. Unix
folks tend to prefer words of one syllable. Exclamation point exclamation
point
takes too long to say.
[5] Because sudo
asks for a password, and that password can grant root
authority, you should always type the full path to sudo
. Unfortunately,
too few sets of instructions acknowledge that principle.
[6] Note that if someone else accesses your account, it also tells them what you’ve been up to. For that reason, some people like to clear out their history regularly.
[7] Should I have written Just like your days, your commands are numbered
?
[8] bang
[9] !$
is typically pronounced bang dollar
, but I suppose that if we
are conserving syllables, we should pronounce it bang buck
.
[12] Also not car rot
, which seems to happen in climates where they
regularly ice the roads.
[14] Yes, there was a time in which we interacted with computers through typewriter-like machines. It even happened during my lifetime.
[15] Insert obligatory joke about the curses we place upon these new displays [16].
[16] It’s okay if you didn’t get that joke. But if you did, could you let me know, even if you didn’t think it was funny?
[17] Strangely enough, the down-arrow doesn’t work when it’s the first key you type. It appears that you cannot look into your command future.
[18] Or is that two things?
Version 1.0 of 2017-01-16.