Linux – Is it possible to have directory aware bash history

bashlinux

I'm I'm not the only one who uses some commands in some directories, different in other directories. When I enter a specific directory from which I run a script with multiple arguments, I'd like to have it in history easily available. Instead, history is spammed by hunderds of other commands from different tabs and windows and it's hard to reach what exactly I was the thing I'd like to rerun.

Imagine you have a server, that you use for very specific script, that script is launched with tons of arguments -x this -y that/thing/there.conf -d -g -t also -t more – whenever you ssh onto that server, to use the script, you'll press up few times and it's there.

So, is there a way to do this on one system, under one user?

Best Answer

First of all, it might be simpler to just map your Up and Down buttons to history-search-backward and history-search-forward respectively. From man bash:

   history-search-forward
          Search  forward through the history for the string of characters
          between the start of the current line and the point.  This is  a
          non-incremental search.
   history-search-backward
          Search backward through the history for the string of characters
          between the start of the current line and the point.  This is  a
          non-incremental search.

With this enabled, if start typing the name of your command and then hit Up, only those commands from your history starting with whatever you've typed will be shown. That way, you can very quickly find the command you're interested in and don't need to fiddle around with directory-specific history files. Just type s, then Up and only commands starting with s will be found. Use fooba and only those starting with fooba will be shown.

To enable this, add the following lines to your ~/.inputrc file on the server (depending on your terminal emulator, you might need a slightly different format. Have a look at my answer here if this one doesn't work):

"\e[A": history-search-backward
"\e[B": history-search-forward

That said, yes it is possible to set a history file per directory. Add this function to your ~/.profile (not to your ~/.bashrc since this file isn't read by default when using ssh to log into a remote machine):

 setHistFile(){
    targetDirs=("/home/terdon/foo" "/home/terdon/bar")
    for dir in "${targetDirs[@]}"; do
        if [[ "$dir" = "$PWD" ]]; then
            ## Set the history file name
            export HISTFILE="./.bash_history"
            ## clear current history
            history -c
            ## read history from the $HISTFILE
            history -r
            ## Exit the function
            return
        fi
    done
    ## This will be run if the PWD is not in
    ## the targetDirs array
    export HISTFILE="$HOME/.bash_history"
    ## Read the history (in case we are leaving
    ## one of the targetDirs)
    history -r
}

And then set your PROMPT_COMMAND variable (this is a command that is executed each time a shell prompt is shown) to it:

export PROMPT_COMMAND='setHistFile'

Change the targetDirs array to the list of the directories you want to have their own history file.

Related Question