# history_logger() side effects:
# sets global variable '_last_history_number_logged'
# $HISTCMD special variable should actually provide this,
# But it appears unavailable in functions or at PROMPT_COMMAND eval time.
#
function history_logger() {
local last_exit_code=$? # must be the first command we run in this function local last_history_line=$(history 1)
local _match_me="^ ?([0-9]+)"
# Only log if we are not root:
if [ "$(id -u)" -ne 0 ]; then
# only log if history number changes:
if [[ ${last_history_line} =~ ${_match_me} ]] &&
[[ ${BASH_REMATCH[1]} != $_last_history_number_logged ]] ; then
_last_history_number_logged=${BASH_REMATCH[1]} ;
echo "$(date)] ${HOSTNAME%%.*}[$$:S${WINDOW}:${last_exit_code}] ${PWD/~/\~} ${last_history_line}" >> ~/.shell.log;
fi ;
fi
}
# the plumbing that makes it work:
export PROMPT_COMMAND='history_logger'
A few explanatory comments, as inline comments aren't available:• HISTCMD does not appear to be available at function call or PROMPT_COMMAND time,
so we use the [[ history =~ regex && BASH_REMATCH ]] to hack it
• the assignment to ${_match_me} is because regex matching doesn't work correctly otherwise.
• the shell out to $(date) seems unavoidable.
• gnu screen is setting $WINDOW
• ${PWD/~/\~} is an exercise left to the reader.
I've seen other folks try to do this –– the best I found folks doing involved calling other bash scripts from the PROMPT_COMMAND.
I hit the same problem (inside a PROMPT_COMMAND, $HISTNUM is always == 1).
My solution uses a regex to capture the last history number, and doesn't require calling a separate script or set of scripts.
Comments welcome.
No comments:
Post a Comment