Created
March 19, 2026 04:21
-
-
Save marcinantkiewicz/290294e2b7fa5263fdbede6e47f6480b to your computer and use it in GitHub Desktop.
Looking up better ways to record history in bash, I found https://github.com/barabo/advanced-shell-history and stopped working on this
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Work on this ended before the thing got much use. Misting trap and PROMPT_COMMAND was too much for my ability to troubleshoot bash | |
| # pain comes from: | |
| # - $? has to be recorded as first command in PROMPT_COMMAND, else it's overwritten by whaever runs first | |
| # - trap debug runs every time, including every command listed in PROMPT_COMMAND | |
| # - history 1 is a good way to get last command, but a pita in zsh | |
| # - PROMPT_COMMAND probably does not capture subshells or pipe components right | |
| # - sqlite does not like concurrent writes, this very much may cause concurrent writes | |
| # just use https://github.com/barabo/advanced-shell-history | |
| # | |
| COMMAND_START_TIME=0; | |
| export SESSION_ID=$(date +%s%N | base64 | tr -d '='); | |
| HIST_DB_FILENAME="$HOME/.terminal_context.db"; | |
| # date is in ISO for sqlite | |
| trap 'COMMAND_START_TIME=$(date "+%Y-%m-%d %H:%M:%S")' DEBUG; | |
| make_shell_hist_db_schema() { | |
| sqlite3 "$HIST_DB_FILENAME" <<EOF | |
| CREATE TABLE IF NOT EXISTS history ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| hostname TEXT, | |
| uid INTEGER, | |
| directory TEXT, | |
| command TEXT, | |
| exit_code INTEGER, | |
| shell TEXT, | |
| session_id TEXT, | |
| start_at DATETIME, | |
| terminate_at DATETIME, | |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| EOF | |
| } | |
| log_hist_to_db() { | |
| local EXIT_STATUS=$1; shift | |
| # recording $? must be the first command that runs in this functioni | |
| local COMMAND_END_TIME=$(date "+%Y-%m-%d %H:%M:%S"); | |
| local CLEAN_CMD=$(printf "%s\n" "$LAST_CMD_TO_LOG" | sed "s/'/''/g"); | |
| local CLEAN_SHELL=$(printf "%s\n" "$SHELL" | sed "s/'/''/g"); | |
| local CLEAN_PWD=$(printf "%s\n" "$PWD" | sed "s/'/''/g"); | |
| local FULL_COMMAND=$(HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"); | |
| if [[ -n "$CLEAN_CMD" && "$CLEAN_CMD" != log_hist_to_db* ]]; then | |
| echo "write to db" >> .debug | |
| sqlite3 "$HIST_DB_FILENAME" "INSERT INTO history (hostname, uid, directory, command, exit_code, shell, session_id, start_at, terminate_at) VALUES ('$(hostname)', '$EUID', '$CLEAN_PWD', '$CLEAN_CMD', '$EXIT_STATUS', '$CLEAN_SHELL', '$SESSION_ID', '$COMMAND_START_TIME', '$COMMAND_END_TIME');"; | |
| fi | |
| } | |
| #make_shell_hist_db_schema | |
| # log_hist_to_db must be the first command in PROMPT_COMMAND, because it must capture exit code before $? is overwritten | |
| export PROMPT_COMMAND="_EXIT_STATUS=$?; log_hist_to_db \$_EXIT_STATUS; history -a; history -c; history -r; $PROMPT_COMMAND" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment