如果 Linux 空闲 5 分钟,则执行命令

17 linux centos terminal bash power-management

我想执行一个命令,例如

 notify-send 'a'
Run Code Online (Sandbox Code Playgroud)

如果我的 Linux 机器闲置了 5 分钟。

闲置,我的意思是被激活的屏幕保护程序用来定义“闲置”的意思。

Dan*_*son 21

我使用一个程序xprintidle来找出 X 空闲时间,我强烈猜测它使用与屏幕保护程序相同的数据源。xprintidle似乎真的没有上游了,但是Debian 软件包还活着。

这是一个非常简单的应用程序:它返回自上次 X 交互以来的毫秒数:

$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932
Run Code Online (Sandbox Code Playgroud)

(注意:由于底层系统的原因,它将始终以毫秒为单位给出一个略低于“实际”空闲时间的值)。

您可以使用它来创建一个脚本,该脚本在闲置五分钟后运行特定序列,例如:

#!/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
Run Code Online (Sandbox Code Playgroud)

100 毫秒的偏移量是因为前面提到的怪癖,xprintidle当像这样执行时,它总是返回比“实际”空闲时间略低的时间。它将在没有此偏移量的情况下工作,然后将更精确到十分之一秒,但它会xprintidle在间隔结束前的最后几毫秒内疯狂地触发检查。无论如何都不是性能猪,但我会觉得那不优雅。

我在 Perl 脚本(一个 irssi 插件)中使用了类似的方法已经有一段时间了,但上面只是写了,除了在编写过程中进行了几次试运行外,还没有真正经过测试。

通过在 X 内的终端中运行它来尝试它。我建议将超时设置为例如 5000 毫秒以进行测试,并set -x直接在下面添加#!/bin/sh以获得信息输出以查看它是如何工作的。


Pet*_*mov 5

xssstate用于此类目的。它suckless-toolsDebianUbuntuupstream中的包中可用。

然后你可以使用以下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
Run Code Online (Sandbox Code Playgroud)