I'd like to be able to set an inactivity timer for a terminal window (OSX) - so if I hadn't typed anything for n minutes it would give a 'beep/alert/run script' - is there a as-yet-unfound-by-me-terminal command/command-line-fu that does this?
-
1Why do you want to do this? Is this for something like keeping an ssh session alive?– terdonJul 19, 2013 at 14:58
-
Actually to remind me that I have open sessions open and that I should either be working on them or close them... I suspose you could use to keep a session alive...– JoeJul 19, 2013 at 20:05
3 Answers
Inactivity timer
Running a delayed command is simple: sleep <sleep time>; run_a_command
Wrapping that in start/stop timer functions:
INACTIVITY_TIME='5m'
INACTIVITY_CMD='echo -ne \a'
function inactivity-start-timer () {
(sleep "$INACTIVITY_TIME"; $INACTIVITY_CMD) &
INACTIVITY_PID=$!
disown
}
function inactivity-stop-timer () {
kill $INACTIVITY_PID > /dev/null 2>&1
}
You can add that your shell rc file. Now you need to run inactivity-start-timer
before every prompt and inactivity-stop-timer
before every command execution. (You don't want a beep if the command takes too long, do you?) Also this assumes you have the system bell on, otherwise put another command into INACTIVITY_CMD
.
Bash
I am guessing you use bash? In that case there is PROMPT_COMMAND to run a command before every prompt. But nothing built-in to run before every command execution. There is a known trick to get that here. So add this also to your .bashrc:
PROMPT_COMMAND=inactivity-start-timer
preexec () {
inactivity-stop-timer
}
preexec_invoke_exec () {
[ -n "$COMP_LINE" ] && return # do nothing if completing
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
preexec "$this_command"
}
trap 'preexec_invoke_exec' DEBUG
Zsh
If you use zsh on the other hand its simpler:
autoload -Uz add-zsh-hook
add-zsh-hook precmd inactivity-start-timer
add-zsh-hook preexec inactivity-stop-timer
Not sure if this is exactly what you're looking for, but GNU Screen has silence monitoring, and tmux does something similar with the monitor-silence command.
I thought this was an interesting thing to figure out. I don't have BSD, so I solved
the problem on Linux. There is something like inotify for BSD, called
kqueue(2), but I don't know if there are convenient monitor tools like
inotifywait
for that kernel fascility.
The idea is to monitor the standard output of a terminal which is a file.
#!/bin/bash
myterm=/dev/`ps -o tty= | head -n1`
if [ $# -eq 0 ] && [ -r $myterm ] && [ ! -d $myterm ]; then
terminal=$myterm
else
terminal=${1:-/dev/pts/1}
fi
function time_out {
echo timeout
loop=false
}
loop=true
timeout=4
while $loop; do
inotifywait $terminal -qq -t $timeout -e MODIFY || time_out
done