Bash – How to exclude command from history list, but to keep it in “live” history

bashcommand history

I've meanwhile managed to keep my history a lot cleaner thanks to you guys' great tips involving the HISTIGNORE option in .bashrc, omitting all those pointless ll or df -k lines.

However, I've learned as well that the HISTIGNORE option is very restrictive, too.
For instance, if you have a line like this (simplified)

HISTIGNORE='ll*:la*:cd*'

you will not only get these to be left out of the list, but also out of your "live history" as I'd like to dub the volatile history you can access via Cursor up/Cursor down. Try it out: they will be entirely omitted now, no matter how long you cycle through your command history with said cursor keys.

However, sometimes I do need these lines, especially with very long and complicated paths which I don't want to retype. On the other hand, I'd like to have these lines exclusive to my live history and not have them stored in the history list as they will change frequently.

Is there any way to accomplish this?

As another side note, I've figured out that for some reason, the "live" history and the history list would sometimes differ a lot (cf. Why do I get different results with the same user and the history command).

Best Answer

You can use HISTIGNORE environment variable.

A colon-separated list of patterns used to decide which command lines should be saved on the history list. For example:

export HISTIGNORE="cd*:ls*"

this will ignore all cd and ls commands from history.

EDIT:

sorry, In my first reading I didn't take sufficent care to your question. Btw, you are right: HISTIGNOREis a very hard setting, and bash_history will simply ignore each command that is listed in this variable (it will ignore it at the moment you execute it, if there are already entries with these command into your HISTFILE they will be found by history reverse search.

To first answer to your last question, live and written history may vary a lot if you use different terminals simultaneously. You could try a solution as described here:

Preserve bash history in multiple terminal windows

What you could imagine is a solution in which you use a function in your ~/.bash_logout file, which will erase the history entries that you do not want.

something like this should do what you want:

 function clear_history(){
    # hist_ignore regex, this may be done in a more fancy way, 
    # such as using an env variable, but anyway
    MYHISTIGNORE='^cd:^view:^cat'

    # write down history to file
    history -w

    # create a new tmp file for history
    tmpFile=$(mktemp)
    cp ${HISTFILE}  ${tmpFile}

    # use it to filter history
    for myRegex in $(echo $MYHISTIGNORE | awk 'BEGIN{FS=":"}{for (i=1;i<=NF;i++){print $i}}'); do 
       sed -i "/${myRegex}/d" ${tmpFile}
    done

    # and copy it back to history file
    mv ${tmpFile} ${HISTFILE}
}