Skip to content

Instantly share code, notes, and snippets.

@tcely
Last active August 24, 2023 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcely/a8c75f08854d8e36f71f45c32d14d20d to your computer and use it in GitHub Desktop.
Save tcely/a8c75f08854d8e36f71f45c32d14d20d to your computer and use it in GitHub Desktop.
Bash History Configuration
if [ "${BASH_VERSION-}" ]; then
# Local variables the functions depend upon
_bash_history_prefix=~/.local/history/bash
# {{{ Begining of the temporary functions block
_bash_history_get_today() {
date '+%Y/0%m/%d'
}
_bash_history_get_now() {
local now
now="${EPOCHREALTIME-}"
if [[ -n "${now}" ]]; then
printf '%s\n' "${now}"
else
date '+%s.%06N'
fi
}
_bash_history_get_path_parts() {
local IFS
IFS=/
set -- $@
while [ $# -gt 0 ]; do
printf -- '%s\n' "$1"
shift
done
}
# prevent path traversal by limiting the arguments
_bash_history_filter_dir_args() {
local dir
# only make dirs that contain only numbers
for dir in $(_bash_history_get_path_parts "${@}")
do
case "${dir}" in
(*[![:digit:]]*) return 1 ;;
esac
done
case "${subdir}" in
# limit to 31 days and 12 months in any year
([[:digit:]]*[[:digit:]]/00[[:digit:]]/3[01]) ;;
([[:digit:]]*[[:digit:]]/00[[:digit:]]/[012][[:digit:]]) ;;
([[:digit:]]*[[:digit:]]/01[012]/3[01]) ;;
([[:digit:]]*[[:digit:]]/01[012]/[012][[:digit:]]) ;;
(*) return 2 ;;
esac
return 0
}
_bash_history_create_dir() {
local dir subdir
subdir="${1:?}"
dir="${_bash_history_prefix:-.}/${subdir}"
if _bash_history_filter_dir_args "${subdir}"; then
test -d "${dir}" || mkdir -p "${dir}"
fi
}
_bash_history_today="$(_bash_history_get_today)"
_bash_history_now="$(_bash_history_get_now)"
_bash_history_create_dir "${_bash_history_today}"
unset -f _bash_history_get_today
unset -f _bash_history_get_now
unset -f _bash_history_get_path_parts
unset -f _bash_history_filter_dir_args
unset -f _bash_history_create_dir
# }}} End of the temporary functions block
# Read the default history file with the default configuration
if shopt -q -o history; then
:
#history -r "${_bash_history_prefix:?}/default"
#history -n "${_bash_history_prefix:?}/default"
history -n
fi
HISTFILE="${_bash_history_prefix:?}/${_bash_history_today:?}/${_bash_history_now:?}"
export HISTFILE
HISTCONTROL='ignorespace:ignoredups'
export HISTCONTROL
HISTSIZE=-1
HISTFILESIZE="${HISTSIZE}"
export HISTSIZE HISTFILESIZE
HISTTIMEFORMAT='%Y+%j %k:%M:%S '
export HISTTIMEFORMAT
HISTIGNORE='bash:bg:dash:dirs:env:exit:fc:fg:history:jobs:pwd:set:sh:vi:vim'
export HISTIGNORE
shopt -s cmdhist
shopt -s histappend
shopt -s histverify
_bash_history_fifo="${_bash_history_prefix:?}/read-previous"
# the fifo exists, or remove whatever may be there and create it
test -p "${_bash_history_fifo}" || {
rm -rf "${_bash_history_fifo}";
mkfifo -m 0600 "${_bash_history_fifo}";
}
# only try this with the fifo ready and history enabled
if shopt -q -o history && [ -p "${_bash_history_fifo}" ]; then
find "${_bash_history_prefix:?}" -name '[[:digit:]]*[[:digit:]]\.[[:digit:]]*[[:digit:]]' -type f -print0 | xargs -0 -r printf -- 'history -n %q\n' >> "${_bash_history_fifo}" &
. "${_bash_history_fifo}"
fi
unset -v _bash_history_fifo
unset -v _bash_history_now
unset -v _bash_history_today
unset -v _bash_history_prefix
# write history to disk before printing the next prompt
declare -a PROMPT_COMMAND
PROMPT_COMMAND+=('shopt -q -o history && history -a')
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment