我想执行如下命令
notify-send 'a'
如果我的 Linux 机器已经闲置了 5 分钟。
我所说的空闲,与激活的屏幕保护程序所定义的“空闲”是同一个意思。
答案1
xprintidle
我使用一个名为“找出 X 空闲时间”的程序,我强烈猜测它使用与屏幕保护程序相同的数据源。xprintidle
似乎不再有上游,但是Debian 软件包活得好好的。
这是一个非常简单的应用程序:它返回自上次 X 交互以来的毫秒数:
$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932
(注意:由于底层系统,它将始终给出一个略低于“实际”空闲时间的毫秒值)。
您可以使用它来创建一个脚本,该脚本在空闲时间五分钟后按照特定顺序运行,例如:
#!/bin/sh
# Wanted trigger timeout in milliseconds.
IDLE_TIME=$((5*60*1000))
# Sequence to execute when timeout triggers.
trigger_cmd() {
echo "Triggered action $(date)"
}
sleep_time=$IDLE_TIME
triggered=false
# ceil() instead of floor()
while sleep $(((sleep_time+999)/1000)); do
idle=$(xprintidle)
if [ $idle -ge $IDLE_TIME ]; then
if ! $triggered; then
trigger_cmd
triggered=true
sleep_time=$IDLE_TIME
fi
else
triggered=false
# Give 100 ms buffer to avoid frantic loops shortly before triggers.
sleep_time=$((IDLE_TIME-idle+100))
fi
done
100 毫秒的偏移量是因为之前提到的怪癖,xprintidle
当像这样执行时,它总是会返回比“实际”空闲时间略低的时间。它在没有这个偏移量的情况下也能工作,然后会更精确到十分之一秒,但它会xprintidle
在间隔结束前的最后几毫秒内疯狂地触发检查。这不会占用任何性能,但我觉得这不太优雅。
我已经在 Perl 脚本(irssi 插件)中使用类似的方法很长一段时间了,但上述内容只是编写的,除了在编写过程中进行了几次试运行外,尚未真正进行过测试。
通过在 X 中的终端中运行它来尝试它。我建议将超时设置为例如 5000 毫秒进行测试,并set -x
直接在下面添加#!/bin/sh
以获取信息输出来查看其工作原理。
答案2
我用它xssstate
来做这样的事情。它的suckless-tools
包装在Debian或者Ubuntu, 或者上游。
然后你可以使用下面的 shell 脚本:
#!/bin/sh
if [ $# -lt 2 ];
then
printf "usage: %s minutes command\n" "$(basename $0)" 2>&1
exit 1
fi
timeout=$(($1*60*1000))
shift
cmd="$@"
triggered=false
while true
do
tosleep=$(((timeout - $(xssstate -i)) / 1000))
if [ $tosleep -le 0 ];
then
$triggered || $cmd
triggered=true
else
triggered=false
sleep $tosleep
fi
done
答案3
如果你使用GNOME Shell,你可以使用 Mutter 显示管理器查询用户会话不活动状态gdbus
,无需任何第三方实用程序。
例如:
# polling interval in seconds
polling_interval=10
# timeout in milliseconds
timeout=300000
while true; do
inactivity=`gdbus call --session \
--dest org.gnome.Shell \
--object-path /org/gnome/Mutter/IdleMonitor/Core \
--method org.gnome.Mutter.IdleMonitor.GetIdletime \
| grep -oP '^(\(uint64\s*)\K\d+'`
if [[ $timeout -lt $inactivity ]] ; then
notify-send 'a'
fi
sleep $polling_interval
done
答案4
bsd ports(软件包集合)有一个程序可以做到这一点:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
例如可以在这里获取:
http://distcache.freebsd.org/local-distfiles/novel/xidle-26052015.tar.bz2
构建如下:
# apt-get install libxss-dev # for include/X11/extensions/scrnsaver.h
# gcc -o /usr/local/bin/xidle xidle.c -lX11 -lXss
请注意,-program 需要包含二进制文件的完整路径,因为它被传递给 execv()。
$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"