-
Notifications
You must be signed in to change notification settings - Fork 0
/
promptcmd
83 lines (74 loc) · 2.6 KB
/
promptcmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#
# called by bash via $PROMPT_COMMAND after a command completes
#
# - expects return value of previous command as sole argument
# - logged timestamps will reflect command completion, not start
#
##############################################################################
prompt_command ()
{
local histnum time_t command file tmuxpid
# TODO find a way to avoid callout to date()
local now_time_t="$(date +%s)"
local now_timefmt="$(date -d @$now_time_t +$HISTTIMEFORMAT)"
# these are the values that get written for our "extra" logs
# that have more information than ordinary bash history logs
#
local logvals=(
$HOSTNAME
$now_timefmt
$TTY_TYPE
$TTY_NUM
$SHLVL
$1 # passed by shell in `$PROMPT_COMMAND': previous
# command result code
)
# was getting "bash: echo: write error: Interrupted system call"
# in the middle of this function because it's run while the
# terminal window is spawning and they both race to finish, so
# sometimes the WINCH can be sent right in the middle of our
# execution and apparently bash does not try to finish the 'echo'
# after it was interrupted (TODO: file upstream bug)
#
trap dowinch=1 WINCH
# read in last command from in-memory history, for saving on-disk
# note: must use raw read (with '-r') or '\n' etc will log as 'n'
# note: $HISTCMD cannot be used to keep track of cancels/dupes
# (we keep $histnum instead) because it's not available in the
# PROMPT_COMMAND function (it's always set to 1) so we get a
# count from the loaded history list, the next one should
# increment it
#
read -r histnum time_t command <<< "$(
HISTTIMEFORMAT="%s "
history 1
)"
LOGLINE="${logvals[*]} $command"
LOGBASH="$(printf "#%u\n%s\n" "$time_t" "$command")"
if [[ $LOGCOUNTLAST && $histnum != $LOGCOUNTLAST ]]
then
# history was incremented, so it's a real command (not
# the first prompt, a ctrl-c, or empty input), log it
#
echo "$LOGLINE" >> $LOGFILE_CMDS
echo "$LOGBASH" >> $LOGFILE_BASH
fi
# set previous value for comparison next invocation
#
LOGCOUNTLAST=$histnum
# there's still a small race window where we might lose a WINCH
# event but at least it won't happen while we write logs, there
# really should be a way to do 'echo' that lets signals queue
# though instead of just interrupting the system call
#
((dowinch)) && kill -WINCH $$
# useful for printing our position in status line, with tmux
# status-interval 0, this avoids needing to poll, and happens
# synchronously too so no need to wait for normal polling lag
#
if [[ $TMUX ]]; then
tmuxpid=${TMUX#*,}
tmuxpid=${tmuxpid%,*}
/proc/$tmuxpid/exe refresh-client -S
fi
}