Bash – Is there some utility or plugin which includes the current directory in the bash history

bashcommand historydirectory

It will be very useful for bash history to display the working directory in which the commands were executed. The history is good for seeing what you did, but it can be hard to tell where you were doing it.

Is there any such plugin or utility, or can bash be configured to add it as well?

Best Answer

You can use the PROMPT_COMMAND feature, add to your .profile/.bashrc :

myprompt() {  
  [[ "$PWD" != "$PREVPWD" ]] && history -s "# cd \"$PWD\""
  PREVPWD="$PWD" 
}  
PROMPT_COMMAND=myprompt

This stuffs a (commented out) cd command into your history each time the current directory changes. It stores $PWD, so anything like cd .. will still record the full path. This appears in your normal history, so it's not the most convenient, and it break shorthands like !$...

Here's better (i.e. over-engineered) version, it checks if the previous command changed directory to an absolute directory to prevent polluting the history:

myprompt() {
  local _seq _date _time _cmd _args
  [[ -z "$HISTTIMEFORMAT" ]] && { 
    ## reads history with no HISTTIMEFORMAT set
    read _seq _cmd _args < <(history 1)
  } || {
    ## this reads history with a HISTTIMEFORMAT='%Y%m%d %H:%M:%S '
    read _seq _date _time _cmd _args < <(history 1)
  }
  ## escaping =~ is troublesome, use variables instead
  local _re1='(cd|pushd|popd)'
  local _re2='^"?/'
  ## check for change-of-directory with absolute path
  [[ "$_cmd" =~ $_re1 && "$_args" =~ $_re2 ]] && {
    PREVPWD="$PWD"
    return
  }
  [[ "$PWD" != "$PREVPWD" ]] && {
     history -s "# cd \"$PWD\""    # stuff into history
     PREVPWD="$PWD"
  }
} 
PROMPT_COMMAND=myprompt

It may need minor tweaking if you have a custom HISTTIMEFORMAT.

You can tweak the history -s operation to instead delete and reinsert/modify the cd,pushd,popd commands, e.g.

  [[ "$_cmd" =~ $_re1 ]] && {
    history -d $_seq  # remove original user command
    history -s "$_cmd $_args # $_cmd \"$PWD\"" # add annotated version
  }

(A tempting option is to change HISTTIMEFORMAT dynamically in the PROMPT_COMMAND function, but this is not added to the history file, it's only applied when you display the history, so it won't work as hoped.)

Bash saves history timestamps as a #nnnn (epoch-seconds) line above each command entry. In principle the $PWD could be added to that line after the timestamp without breaking anything, but some non-trivial code changes would be required to properly support this.

Related Question