Linux Tips - Better History
Most people know there's a command history in Bash that you can get at when you use the incremental search or using the up arrows, or with the !
operator. But what you might not realize is that you can use it more effectively and modify how it saves your history. This is a tip on making it behave better and more predictably.
.bashrc
and source
Just a quick note: Generally you will want to save any changes you make to your .bashrc
file so that they persist and take effect when you open new terminals. If you are following along in the examples here and writing them to your .bashrc
file, don't just close and re-open your terminal to see the effects, instead, do the following command and keep your terminal open:
source ~/.bashrc
The reason for this is that some of these settings effect the way your history is stored and their effects may not be as obvious if you close your terminal and inadvertently rewrite your history.
the basics of history
Every time you type a command and hit enter, that command is stored in your history. When you exit the terminal, that history will be written to the ~/.bash_history
file, provided that your session is exited normally.
You can press up and down to go through your history, and when you find the command you want, you can edit it in the typical fashion and hit enter to run it.
You can type the history command to see your recent commands. The number to the left of the command can be used to execute that entry of your history by typing an exclamation point followed by the number. For example, if this were my recent history:
436 clear
437 cat ~/.bash_history
438 clear
439 pwd
440 cd Downloads/
441 clear
442 ~/youtube-dl 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
443 ls
In this scenario, I can type !443
and it will run the ls
command when I hit enter.
Typing the exclamation point and then the first word of a command in the history will run that command. Using the same history above as an example, !cl
will run the clear
command when I hit enter.
Typing a space in front of any command will prevent that command from being saved to your history. I generally use a space before I run any history command so that the history command is not saved to my history. For example, I type spacehistory | less
so that I can scroll through my history, and when I'm done, that command will not end up in my history. That way I don't end up with a dozen pointless history commands in my history.
rewriting history
Sometimes you want to delete stuff from your history. You can do this by editing the .bash_history
file if the command was already written out, or by using the history
command. For example, using the previous history:
436 clear
437 cat ~/.bash_history
438 clear
439 pwd
440 cd Downloads/
441 clear
442 ~/youtube-dl 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
443 ls
If I were to execute history -d 443
it would remove that ls command. However, it would also show up in the history, so I would probably put a space in front of the command to prevent this.
If I wanted to clear the entire history, I could use history -c
, but note this does not eliminate the history that has already been saved to ~/.bash_history
, it only deletes the history of the current shell session.
If I wanted to make sure my history was saved, I could use history -w
and the current session would be written to disk.
shopt
for shell options
There is a command for controlling many obscure shell options, namely, shopt
. For the complete set of options and their purposes, dig through the Bash manual page and look for the builtins. I'm only covering the ones that deal with history here.
I like to use !
to run commands from my history, but I'm error prone, so I set up the option to display the commands run with !
upon pressing enter instead of running them. This is controlled by the histverify
shell option. For example, I have shopt -s histverify
in my .bashrc
file. Now, instead of immediately running the first matching history entry, the !
will display the command before I run it. For example, if I type the following and press enter:
$ !cl
Then Bash will fill in the following command, but I have to press enter to run it:
$ clear
This works for numbered commands, too. I could have typed !441
and it would have had the same result.
Another option I like is the histappend
, the history file will no longer be clobbered by the last exiting shell and instead it will get every command appended to it.
kill with the right signal
Once you've carefully edited your history file for maximum efficient use in the future, or just to eliminate all traces of that Rick Astley video you downloaded, you may not want the current session history to be written to disk. An easy way to prevent the session from saving is to send a kill to it. And I find the easiest way to do that is with a convenience shell variable that fetches the current process id ($$
). So, to terminate your shell session immediately, without saving the history, run a kill -9
on your current shell:
kill -9 $$
Summary
In summary, you can control what gets written to your history, you can edit what has already been written to your history, and there are some options that control these settings that you might want to change.
command | description |
---|---|
history -w | Write out the session history to .bash_history |
history -c | Clear the current session history |
history -d N | Delete the Nth item from history |
kill -s $$ | Kill the current shell, without saving history |
shopt | description |
---|---|
histverify | Displays ! commands on enter instead of just executing them. |
histappend | Append new session history to the end of .bash_history instead of clobbering it. |
References
Other tips:
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit