If you've worked in the terminal, it's likely you're in some way proficient with the command history features of your shell. There's a lot more functionality than many realise however, and learning it can help you eliminate a lot of duplicate typing.
If you've worked in the terminal, it's likely you're in some way proficient with the command history features of your shell. There's a lot more functionality than many realise however, and by learning it you can eliminate a lot of duplicate typing.
The first thing most people learn about the command history is that you can go back and forward through your history with the up and down keys. Bash stores history entries between shells by default (on most distributions), so you should have access to the commands you typed previously, regardless of which terminal you're currently working in. You can turn this behaviour off, so that history works only for the current invocation of the shell you're using by adding the following line to one of your start-up files (say, ~/.bashrc):
The amount of commands stored in the history file is dependent on the size of the file you allocate. By default 500 commands are stored, but you can tweak these values by setting the following options in a startup file:
HISTSIZE = 1000 HISTFILE = ~/.bash_history
To print out the entire history file, you can use the
$ history | tail -10 522 gvim 523 vim .bashrc 524 vim .bash_profile 525 history 526 ls 527 echo $SHELL 528 echo $HISTFILE 529 echo $HISTSIZE 530 vim .bashrc 531 history | tail -10 $
The number in the left column is the history item number. This can be bigger than the size of your stored history file, as commands from the current shell are not added to the file until the shell is closed.
You can jump straight to executing any line in your history by typing an '!' followed by the item number. So for example if we wanted to echo the shell name to the console again we could write
echo $SHELL or simply:
$ !527 /bin/bash $
Searching command history
You can also use the ! command to search through the history, by replacing the item number with characters from the start of the command. The previous example can now just as easily be written:
$ !echo echo $SHELL /bin/bash $
Often this becomes unwieldy since you have to match the command from the beginning, and many commands start in the same way (eg. "echo $HISTFILE", "echo $HISTSIZE", "echo $SHELL"). You can always hack something together using history and grep, but there's an easier way with the '!?' command. '!?' followed by a simple string, executes the last command in the history that contains that string.
So, to reprint the name of the shell we could have simply typed:
$ !? SHELL /bin/bash #
More usefully, you can interactively search the command history at the console by hitting CTRL-R at the prompt and typing the section of the string you are looking for. You can only use CTRL-R interactively, that is, not in a script (although relying on the history in a script can be dangerous anyway), but it can save you more keystrokes as it displays the match at each point, meaning you can stop searching once you've found it.
The previous example using CTRL-R interactive search:
(reverse-i-search)`SH': echo $SHELL
The HISTIGNORE environment variable controls which commands are entered into the history and which are ignored. It contains a list of patterns separated by colons (':') that when matched, drops a command rather than includes it in the file. So for example, if you don't need to see the 'history' program in the command history (since it's fairly redundant), you could do the following:
$ export HISTIGNORE="history" $ history ... $ history | tail -1 581 export HISTIGNORE="history" 582 history | tail -1
You can see here that the line with simply
history on it has not been added to the list, while the
history | tail -1 has -- only exact matches in the HISTIGNORE list are filtered out. If you don't want any lines beginning with history to be in the command history you can amend your HISTIGNORE variable to:
$ export HISTIGNORE="history*"
Be warned however than ignoring an item from the history means that it cannot be recalled by any means -- not even with the up and down arrows. If you still wish to keep this behaviour for all commands, but not have them show up in a history file, you may be better served by leaving HISTIGNORE alone and trimming the file with a script on logout.
Some people use this variable to keep their history file nice and tidy, by removing the commands that they're unlikely to bother recalling, such as
exit. Another good tip comes from this page which includes the tip that if you add
"[ \t]*" to your HISTIGNORE variable you can make any command be ignored by starting it with a space. Good if you need a little extra privacy for some commands.