我想在用户变为非活动状态(系统空闲)时运行命令。例如:
echo "You started to be inactive."
Run Code Online (Sandbox Code Playgroud)
此外,当用户再次活跃时(系统不再空闲):
echo "You started to be active, again."
Run Code Online (Sandbox Code Playgroud)
我需要一个可以执行此操作的 shell 脚本。如果没有计时器/间隔,这可能吗?也许是一些系统事件?
Jas*_*per 22
ArchLinux 论坛上的这个线程包含一个简短的 C 程序,它查询 xscreensaver 以获取用户空闲时间的信息,这似乎非常接近您的要求:
#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);
}
Run Code Online (Sandbox Code Playgroud)
将其另存为getIdle.c并编译
gcc -o getIdle getIdle.c -lXss -lX11
Run Code Online (Sandbox Code Playgroud)
得到一个可执行文件getIdle。该程序以毫秒为单位打印“空闲时间”(用户不使用鼠标移动/单击,不使用键盘),因此基于此构建的 bash 脚本可能如下所示:
#!/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
Run Code Online (Sandbox Code Playgroud)
这仍然需要定期轮询,但它可以完成您需要的一切......
这并不完全是您所要求的,但总是有batch- 命令(通常是 - 命令的特殊调用at并使用atd- 守护进程)。
batch允许您在平均负载低于某个限制(通常为 1.5,但这可以在启动时设置atd)时提示要运行的命令。还可以以at这样的方式提示作业,而不是在某个特定时间运行;该作业只是batch在那时交付,并在平均负载下降时首次运行(例如,一旦凌晨 2:00 后的某个时间平均负载下降到 1.5 以下,它就会运行)。
不幸的是,批处理作业将运行到最后,如果计算机不再空闲,它也不会停止。
+++
如果您必须走编程路线(从其他答案看来是这样),我想我会尝试制作类似于atd或crond守护进程的东西,来监视登录用户和/或平均负载。然后,该守护进程可以从某个目录运行脚本/程序,并根据需要启动/继续或停止它们(使用信号)。