Run a command when system is idle and when is active again
This thread on the ArchLinux forums contains a short C program that queries the xscreensaver for information how long the user has been idle, this seems to be quite close to your requirements:
#include <X11/extensions/scrnsaver.h>
#include <stdio.h>
int main(void) {
Display *dpy = XOpenDisplay(NULL);
if (!dpy) {
return(1);
}
XScreenSaverInfo *info = XScreenSaverAllocInfo();
XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info);
printf("%u\n", info->idle);
return(0);
}
Save this as getIdle.c
and compile with
gcc -o getIdle getIdle.c -lXss -lX11
to get an executable file getIdle
. This program prints the "idle time" (user does not move/click with mouse, does not use keyboard) in milliseconds, so a bash script that builds upon this could looke like this:
#!/bin/bash
idle=false
idleAfter=3000 # consider idle after 3000 ms
while true; do
idleTimeMillis=$(./getIdle)
echo $idleTimeMillis # just for debug purposes.
if [[ $idle = false && $idleTimeMillis -gt $idleAfter ]] ; then
echo "start idle" # or whatever command(s) you want to run...
idle=true
fi
if [[ $idle = true && $idleTimeMillis -lt $idleAfter ]] ; then
echo "end idle" # same here.
idle=false
fi
sleep 1 # polling interval
done
This still needs regular polling, but it does everything you need...
TMOUT in bash will terminate an interactive session after the set number of seconds. You may use that mechanism.
You migth capture the logout by setting an according trap (I did not test that), or by using the bash-logout-scripts (~/.bash_logout).
Here is a good superuser-answer into that direction.
This is not quite what you asked for, but there is always the batch
-command (usually a special invocation of the at
-command and using the atd
-daemon).
batch
lets you cue-up a command to be run when the load-average drop below a certain limit (usually 1.5, but this can be set when starting atd
). With at
it's also possible to cue a job in such a way that rather than being run at a certain time; the job is just delivered to batch
at that time, and first run when the load-average drops (eg. it's run as soon as the load-average drops under 1.5 sometime after 2:00am).
Unfortunately a batch-job will then run to it's end, it will not stop if the computer is no-longer idle.
+++
If you have to go the programming-route (which it looks like from the other answers), I think I'd try to make something similar to the atd
or crond
daemons, that monitored logged-in users and/or load-average. This daemon could then run scripts/programs from a certain directory, and start/continue or stop them (with signals) as needed be.