A useful feature of the
bash shell is the command recall, or history, usually accessed via the up arrow. It’s one of the first command line features we learn about, but – as is often the way – there’s more to it than initially meets the eye.
Almost every command we execute is stored in the
history file, which is defined by the
HISTFILE environment variable. As we can see here, the default value is
$ echo $HISTFILE
You can change that if you wish by changing the value
HISTFILE environment variable, or unset it to disable the saving of history (see also Linux Tips: Keeping Commands out of Command Line History).
All the time we have only one shell session, the command recall works as we’d expect. Once we are using multiple shell sessions on one system, it’s possible for commands to apparently disappear from history. By default, the shell only writes the history file when it exits, and it does so by overwriting the current history file.
That means that when you start a shell, its command history doesn’t have the commands from any currently open shell. As you close the shell sessions, the history file will be rewritten, and only the commands from the shell session that is closed last will persist.
The fix is to make two changes:
- we need commands to be appended to the history file rather than overwriting it
- we need to update the history file after each command rather than when the shell exits
Both can be achieved by editing
~/.bashrc and adding the following two lines:
shopt -s histappend
PROMPT_COMMAND="history -a;history -r;$PROMPT_COMMAND"
The first line causes commands to be appended rather than overwriting. The second line defines a compound command to be run every time the shell prompt is displayed. First we run
history -a, which appends the new history lines to the history file. Then we run
history -r, which reads the content of the history file and appends it to the current history buffer.
The end result is that all terminal sessions will update the history file as each command is executed. Each time the command prompt is printed, the history for that session will be updated with any commands issued in other terminals. Set up two shell sessions and try it.
While you’re making the changes above, you may want to also add in:
HISTTIMEFORMAT='%a %d %b %Y, %X: '
Now when you run the history command, you’ll see when each command was issued:
$ history|tail -6
50024 Fri 10 Nov 2017, 19:15:21: ssh 10.0.0.1 -l kae
50025 Sun 12 Nov 2017, 10:26:09: ssh koinex
50026 Sun 12 Nov 2017, 13:05:31: plan
50027 Sun 12 Nov 2017, 14:54:14: cd
50028 Sun 12 Nov 2017, 14:54:15: cd ownCloud/
50029 Sun 12 Nov 2017, 14:54:18: gvim writing.otl
Could This Linux Tip Be Improved?
Let us know in the comments below.