3

I was wondering if it is possible to keep a file containing history per current working directory. So for example if I was working in /user/temp/1/ and typed a few commands, these commands would be saved in /user/temp/1/.his or something. I am using bash.

3

Building off the answer provided by Groggle, you can create an alternative cd (ch) in your ~/.bash_profile like.

function ch () {
    cd "$@"
    export HISTFILE="$(pwd)/.bash_history"
}

automatically exporting the new HISTFILE value each time ch is called.

The default behavior in bash only updates your history when you end a terminal session, so this alone will simply save the history to a .bash_history file in whichever folder you happen to end your session from. A solution is mentioned in this post and detailed on this page, allowing you to update your HISTFILE in realtime.

A complete solution consists of adding two more lines to your ~/.bash_profile,

shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

changing the history mode to append with the first line and then configuring the history command to run at each prompt.

  • 1
    You should note that this configuration is highly dangerous. Sooner or later you're going to leak some confidential commands in a publicly exposed archive or repository. On a multiuser machine, as soon as you change into another user's directory and run a few commands there, they can modify your files and probably gain a backdoor to your account. And other users, or people whose archives you download, can easily trick you into running commands by injecting them into your shell history. – Gilles 'SO- stop being evil' Aug 24 '16 at 23:15
  • Great, I didn't think about that, thanks very much. – tafelplankje Aug 25 '16 at 13:24
2

You can set up code to be executed when changing directories. In zsh, this is as simple as defining a function and adding it to the chpwd_functions array. In bash this takes a little more work but you can do it as well; see Execute bash scripts on entering a directory for how to define a chpwd function that is executed on each directory change.

For what you want to do, the chpwd function needs to write the current history to the old file. To save the history to the right place when exiting bash, set the HISTFILE variable to the history file for the new directory, and read the new history.

chpwd () {
  history -a
  mkdir -p "$HOME/.bash_history.d/${PWD%/*}"
  HISTFILE=~/.bash_history.d/$PWD
  history -r
}

Note that I write the history to a hierarchy under your home directory, not to the current directory. Writing shell history to the current directory would be extremely dangerous and disruptive: you'd end up with privacy leaks all over the place, you'd risk modifying unintended files (what if the history file name is an existing symlink to some other place?), etc.

It would probably be better to write out the history after each command. In bash, you can enable this with the histappend option. With this option, you don't need to run history -a explicitly.

shopt -s histappend
chpwd () {
  mkdir -p "$HOME/.bash_history.d/${PWD%/*}"
  HISTFILE=~/.bash_history.d/$PWD
  history -r
}
0

Depending on how frequently you change directories my solution might not work. You can export the HISTFILE which sets where bash history is stored, so the idea is that you can make separate profiles in the directories that you're working in and then automatically load them using something like direnv.

HISTFILE="$(pwd).bash_history"

Direnv https://github.com/direnv/direnv

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.