4

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?

4

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.

  • Are any of the other shells, such as zsh likely to offer a better alternative? When you talk about non-trivial code changes to add some information to the timestamp, do you mean changes to the history command's C source or the my_prompt code? – vfclists Apr 24 '17 at 7:45
  • 1
    There's an ancient (2009, predating U&L) duplicate that has some more solutions, including zsh options: stackoverflow.com/questions/945288/… . The Advanced Shell History project is still maintained. Code changes would be for bash itself for reading/writing the history data, the history command doesn't provide access to the internals of the history file. – mr.spuratic Apr 27 '17 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.