Linux – How to make bash keep most frequently used history entries for ever

bashcommand linehistorylinux

Duplicates are already turned off, but that's not enough (I feel like I have to enter commands too often).

Assume I have a capacity of 2000 entries of by bash history and a command which I used very often (n times) in the past but not recently and I want to use again now. Assume this command is at the oldest position in the history and would be evicted after the next non-duplicate command execution. I would like this command to be preserved and the oldest command (with usage count < n) to be evicted from history instead.

One might argue that this makes the bash history not a (linear) history anymore. I agree, but don't care since I want easy access to my favorite commands (being automatically collected).

I'm using bash 4.3.42 on Ubuntu 15.10.

Best Answer

Warning: This is not an answer to the question as it stands, but rather a suggestion for an approach that you may find useful.

I feel your pain. I like to keep around my Bash history as well, and be able to recall commands that I might have run a long time ago. I have developed an approach that allows me to keep all of my Bash history within a reasonable history size.

  1. my Bash history settings are:

    HISTCONTROL=ignoreboth:erasedups
    HISTIGNORE="?:??:???:$HISTIGNORE"
    

    That helps to keep down the entries that end up in the Bash history in the first place. Commands like ls are shorter to type than to recall, so there's no point in storing them (that's what HISTIGNORE is for). ignoreboth is shorthand for ignorespace and ignoredups. The former prevents entries with a leading space from ending up in the history. I use it for commands that I know I will never recall, or never want to recall, like rm -rf * :). There's plenty more stuff that I ignore by default (not shown), which keeps the history size down.

  2. Despite the countermeasures above, duplicates still end up in my history (e.g., due to multiple Bash shells open at the same time). I have a counter in my prompt that shows me the current history size

    PS1='\u@\h:\w:\!> '
    

    (The relevant code is \!, a.k.a. history number of this command.) That shows me when it is time to 'clean up' (see next step).

  3. I periodically 'clean up' my Bash history by running the following command:

    tac ~/.bash_history | awk '!seen[$0]++' | tac > ~/.bash_history.new && mv ~/.bash_history.new ~/.bash_history
    

(presuming your Bash history is stored in ~/.bash_history of course). This command removes duplicates while respecting order: commands used last remain last. Only the last (most recent) duplicate is retained.

With this approach, I've been able to keep all of my Bash history within a very modest history size of 600 to 1000 entries.