5

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).

syntaxerror
  • 2,246

2 Answers2

2

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}
}
Danduk82
  • 482
0

3 possible options

Ran out of time - Corrections welcome

0) Setup aliases to allow you to temporarily save every command to history

alias histsave='$HISTIGNORE && HISTIGNORESAVED=$HISTIGNORE; HISTIGNORE=""; echo "Saving all commands in history"' # History save all

alias histignore='$HISTIGNORESAVED && (HISTIGNORE=$HISTIGNORESAVED; echo "Not saving: $HISTIGNORE commands in history"; exit(0)) || echo "I got nutn."' # History ignore some

1) Type complex commands into a second bash session.

Set up an alias say: alias histig='HISTIGNORE=""'

In a terminal. Right click and split horiz/vertically or other way to launch a new session at same location.

histig

enter complex command # Will normally be saved in history

Optionally:

history -w # To save for use in other terminal sessions using history -r

2) Store complex commands as one-offs using a comment

Prefix the command with #, making it a comment:

Hit: Home, #, enter. It's now in your history.

Hit: Up arrow, home, delete (the #), enter ... to run the command.

Upsides:

Allows your history to normally exclude your HISTIGNORE setting. Can grep history for '#' to find these particularly useful commands.

Work-around:

If you save commands in your history you could use '##' for this.

Downsides:

You would be saving the command, even if it didn't work first time as required/expected.

Some of this may not work for you == YMMV

tebb
  • 1
  • 3
    This question has been on the site for five years; if you feel you need more time to answer properly, please take it. That said, Stack Exchange is a collaborative site where others are welcome to improve posts. – Jeff Schaller Jan 31 '21 at 22:41