Distributed eternal bash history

As a developer you spend much of your time working in the terminal, every command written gets saved to history. How history is written and preserved, however, is highly configurable.

Wouldn’t it be nice, when you hit Ctrl-R, that the ssh-tunnel command you used four weeks ago was still there? Or if you do a “history | grep some-neat-trick-i-did-last-year” you found it? What if the commands you wrote on your work-station were instantly available on your laptop?

If you use a terminal, and you wish these things were true, this blog post is for you.

Before we get into the details, we need a bit of background. History in the terminal is split in two; first there is the history list, which contains the commands from the current session in memory. Second, there is the history file, where the history list form each session is written when the session is closed, and read from when a new session is created.

This is the reason, when you have multiple terminals open, commands will not be in the history of shell-1 if written in shell-2.

Let us take a closer look at the history command. When executed without parameters, it will return the history list, or in other words, the history for the given session.

The history command can also take several options, here are a few of interest:

  • history -a “Append history list to history file”
  • history -c “Clear history list from session”
  • history -r “Read from history file and append the contents to history list”

With this we have all the tools we need to make the history distributed between sessions. It can be done by writing the history list to the history file, clear the history list, and then read from the history file before each command. This is done by leveraging the PROMPT_COMMAND environment variable, which is executed before each command prompt.

For example, like this:

PROMPT_COMMAND="history -a; history -c; history -r; ${PROMPT_COMMAND}"

What about the limits for the history list and history file? This can be resolved by setting a blank value for HISTSIZE and HISTFILESIZE, which is interpreted as unlimited.

export HISTSIZE=

Make sure to comment out or overwrite existing config for these variables in your .bashrc file. For recent versions of Ubuntu HISTSIZE is set to 1000 and HISTFILESIZE is set to 2000. The default for both, if unset, is only 500 lines.

Another thing to look out for is the name of the history file. Various programs, like screen, can sometimes truncate the default file found in ~/.bash_history, to avoid this simply set the HISTFILE environment variable to something else than the default.

export HISTFILE=~/.bash_eternal_history

Now you have eternal bash history with shared sessions, but only on one machine. Why stop there? By leveraging a shared-folder application, bash history can easily be distributed between machines. Lets use Dropbox as an example.

All you need is to point your HISTFILE to a file that is located on dropbox, and do this on every machine you want to share history. This can be done by either symlink or full path.

export HISTFILE=~/Dropbox/.bash_eternal_history

To get all of this working can be a bit of tinkering, and if you do not want to (or bother) to do it yourself, I wrote a script that will configure this for you. Head over to https://github.com/ivaruf/eternalize-bash and look for install instructions.

Running the script will prompt you to configure with or without dropbox, this can be changed later by re-running the script. History from your old history file will be moved to the new one and if something goes amiss, a backup is stored to ~/.bashrc_backup before any changes are made. The script will also run fine on OS X and Windows using git bash.

If a bash terminal is not your cup of tea and you use another shell variant like Zsh, configuration should be quite similar, using the same environment variables.

About the author:

Ivar Fredriksen is a Solutions Engineer at Iterate Norway. He has been working as a consultant with both front-end and back-end for over five years. Find him on Github.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s