我想在用户变为非活动状态(系统处于空闲状态)时运行命令。例如:
echo "You started to be inactive."
同样,当用户再次活动时(系统不再处于空闲状态):
echo "You started to be active, again."
我需要一个可以执行此操作的shell脚本。没有计时器/间隔就可以吗?也许一些系统事件?
我想在用户变为非活动状态(系统处于空闲状态)时运行命令。例如:
echo "You started to be inactive."
同样,当用户再次活动时(系统不再处于空闲状态):
echo "You started to be active, again."
我需要一个可以执行此操作的shell脚本。没有计时器/间隔就可以吗?也许一些系统事件?
Answers:
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);
}
另存为getIdle.c
并编译
gcc -o getIdle getIdle.c -lXss -lX11
获取可执行文件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
这仍然需要定期轮询,但是它可以满足您的所有需求...
xprintidle
,大多数发行版中都提供,并且功能完全相同。
在设置的秒数后,bash中的TMOUT将终止交互式会话。您可以使用该机制。
您可以通过设置相应的陷阱(我没有测试过)或使用bash-logout-scripts(〜/ .bash_logout)来捕获注销。
$TMOUT
几秒钟后如何执行命令而不是注销的问题。
EXIT
陷阱或从中止注销.bash_logout
。
这并不是您所要求的,但是总是有batch
-command(通常是-command的特殊调用,at
并使用atd
-daemon)。
batch
当负载平均下降到某个限制(通常为1.5,但可以在启动时设置atd
)以下时,让您提示要运行的命令。有了at
它也可以以这样的方式来提示一份工作,而不是在特定时间运行; 该作业仅batch
在那时交付,并在平均负载下降时首先运行(例如,在凌晨2:00之后某个平均负载下降到1.5以下时,它将立即运行)。
不幸的是,批处理作业将一直运行到最后,如果计算机不再处于空闲状态,它也不会停止。
+++
如果您必须执行编程路线(从其他答案中可以看到),我想我会尝试制作类似于atd
或crond
守护程序的内容,以监视已登录的用户和/或负载平均。然后,该守护程序可以从某个目录运行脚本/程序,并根据需要启动/继续或停止它们(带有信号)。
.lock
文件,则可以轻松解决计时问题。
该线程具有基于检测键盘和鼠标活动的几种解决方案。我xprintidle
从每隔几分钟开始的Cron作业开始。但是正如他们指出的那样,它xprintidle
是不需要维护的,因此您可能需要安装Perl模块并使用它:
$ cpanm X11::IdleTime
...
$ sleep 10; perl -MX11::IdleTime -le 'print GetIdleTime()'
9
如果UI没有足够的空闲,我将使用从cron轮询的任何一种解决方案,该脚本会在顶部退出。当然,脚本需要使用export DISPLAY=:0.0
才能与X11对话。
请记住,在观看电影或运行大量CPU任务时,键盘和鼠标可能处于非活动状态。
我不知道不轮询某种系统状态就可以做到这一点的方法,例如其他答案使用屏幕保护程序或bash空闲计时器,或从.bash_logout运行,但这是检查CPU使用率的一种方法。
这仍然涉及每n秒轮询一次,并且如果您的CPU使用率低于您选择的任何数量,那么您就可以编写要运行的脚本。但是,无论您执行任何操作都可能会增加CPU使用率,但是您可以在“东西”上使用nice来不计算它。
这是一个使用top的测试脚本,但是您可以使用mpstat代替,或者检查平均负载呢?
while true
do
idle=$(top -bn2 | grep "Cpu(s)"|tail -n 1|sed "s/.*, *\([0-9.]*\)%* id.*/\1/")
echo "idle is $idle"
if [[ $idle > 90 ]]
then
echo "idle above 90%"
echo "Do stuff now"
else
echo "idle below 90%"
echo "Stop doing stuff now"
fi
sleep 1
done
那只是我放在一起测试从顶部读取空闲状态的脚本。您可以解析,/proc/stat
但我认为它只显示总时间,您需要比较一个时间间隔内的结果。Top对我来说是个问题(Linux mint 16),在第一次运行时,它似乎永远不会更改cpustats,好像它必须等待解析/ proc / stat本身一样,因此top -bn2
理论上top -bn1
应该可以。
w
显示用户空闲时间的命令。-顺便说一下,对于我来说,我只是想检测闲置状态以使机器进入睡眠状态,以节省电源,而轮询与此相反。