put in bash or zsh history absolute path to files I working on

I have found that in bash i frequently use something like that:

  • vim ./somefile1 less
  • less ./dir1/dir2/somefile2
  • cp some_other_relative_path_to_file

and so on

After that when I trying to find a command in history and run it I get an error because I am in a different directory now. Is it possible to configure bash to "expand" relative path to files with absolute one when they go to history?


One solution would be to rewrite history so that when you run this:

ls

it gets saved as:

cd /current/directory && ls

For Bash there is a trick to modify its history, as explained in this great stackoverflow answer. You'll need to use a Bash shell variable called PROMPT_COMMAND.

When set, its contents are executed every time before the prompt is shown. Setting it to this:

export PROMPT_COMMAND='hcmd=$(history 1); hcmd="${hcmd# *[0-9]*  }"; if [[ ${hcmd%% *} == "cd" ]]; then pwd=$OLDPWD; else pwd=$PWD; fi; hcmd=$(echo -e "cd $pwd && $hcmd"); history -s "$hcmd"'

will rewrite history as described above.

Try it first in a Terminal window and if you are happy with it, add it to your .bashrc file to enable it.

The downside is that, in its current incarnation, all commands will be prefixed with cd /some/dir, which decreases readability and can get annoying for commands like cd /usr/local:

$ history | tail -n 5
  522  cd /Users/jaume && cd /usr/local
  523  cd /usr/local && file bin/ls
  524  cd /usr/local && cd ~
  525  cd /Users/jaume && file Documents/.localized 
  526  history | tail -n 5

You could of course modify PROMPT_COMMAND to only rewrite history for a reduced number of commands.