Skip to main content
1 of 2

Have a look at https://gist.github.com/codemedic/b2cb583973f8dd3a291c56c1f5348efa

It is based on some of the ideas discussed here already. It keeps the history in a separate directory under ~/.bash_history.d/, to avoid accidental commit of the file to VCS (git) etc.

# The base path for the history files created by ch ch_history_base_path="$HOME/.bash_history.d" # ch_hist_file is a helper function to get the history file for a given directory. # If no directory is given, it will use the current directory. ch_hist_file() { local dir dir=$(realpath "${1:-.}") # Check if the directory is under the home directory using a prefix match if [[ "$dir" != "$HOME"* ]]; then echo "ch: Directory is not under the home directory" 1>&2 return 1 fi local history_file="${ch_history_base_path}/${dir#"$HOME"}.bash_history" echo "$history_file" } # ch is a function to change the current directory and load the history file for that directory. ch() { # Check if we are already in a ch shell if [[ "${__ch_load_history:-0}" == "1" ]]; then echo "ch: Already in a ch shell" 1>&2 return 0 fi local dir dir=$(realpath "${1:-.}") local history_file if ! history_file="$(ch_hist_file "$dir")"; then return 1 fi echo "ch: Loading history file $history_file" 1>&2 # Make directory if it does not exist mkdir -p "$(dirname "$history_file")" # Create the history file if it does not exist touch "$history_file" # Set the history file for the new shell export HISTFILE="$history_file" # Set the history size for the new shell export HISTSIZE=${HISTSIZE:-1000} export HISTFILESIZE=${HISTFILESIZE:-2000} # Open a new shell with the history file set to the current directory # Use the --rcfile option to set the history file for the new shell. exec bash --rcfile <( echo ". ~/.bashrc" echo "export HISTFILE='$history_file'" echo "export HISTSIZE=$HISTSIZE" echo "export HISTFILESIZE=$HISTFILESIZE" echo "export __ch_load_history=1" echo "builtin cd \"$dir\"" ) } # ch_autoload is a helper function to check if the history file exists and run `ch` if it does. ch_autoload() { local history_file if history_file="$(ch_hist_file)" && [[ -f "$history_file" ]]; then ch . fi } # auto_ch is a wrapper function for the builtin cd command that autoloads the history file. Intended to be used as an alias for cd. auto_ch() { # Run the builtin cd command first builtin cd "$@" || return $? # Autoload the history file if it exists ch_autoload } alias cd=auto_ch