如果Linux闲置5分钟,请执行命令


16

我想执行一个命令,例如

 notify-send 'a'

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

闲置是指被激活的屏幕保护程序用来定义“空闲”的同一件事。


好,您尝试了什么?谷歌怎么说?您是否尝试找出屏幕保护程序如何检测到此情况?请花一些时间进行搜索,然后再在此处发布问题,并通读“ 如何提出一个好问题”
2013年

我只找到一个程序,xautolock但没有示例

Answers:


20

我使用了一个名为xprintidleX的空闲时间程序,我强烈猜测它会使用与屏保相同的数据源。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 ms的偏移量是由于前面提到的怪异,xprintidle当执行这种怪异时,总是会返回比“实际”空闲时间稍短的时间。它将在没有此偏移的情况下工作,然后将精度提高到十分之一秒,但是它将xprintidle在间隔结束之前的最后几毫秒内疯狂地触发检查。绝不以表现为生,但我会觉得这很不雅。

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

通过在X的终端中运行它来进行尝试。我建议将超时设置为例如5000 ms进行测试,然后set -x直接在下面添加#!/bin/sh以获取有用的输出,以查看其工作原理。


5

xssstate用于此类目的。它可以在DebianUbuntu上游的suckless-tools软件包中使用。

然后,您可以使用以下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

1

这是我发现可以编译的C应用程序。

$ more xidle.c 
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/scrnsaver.h>

/* Report amount of X server idle time. */
/* Build with- */
/* cc xidle.c -o xidle -lX11 -lXext -lXss */


int main(int argc, char *argv[])
{
    Display *display;
    int event_base, error_base;
    XScreenSaverInfo info;
    float seconds;

    display = XOpenDisplay("");

    if (XScreenSaverQueryExtension(display, &event_base, &error_base)) {
    XScreenSaverQueryInfo(display, DefaultRootWindow(display), &info);

    seconds = (float)info.idle/1000.0f;
    printf("%f\n",seconds);
    return(0);
    }
    else {
    fprintf(stderr,"Error: XScreenSaver Extension not present\n");
    return(1);
    }
}

它需要几个库来构建。在我的Fedora 19系统上,我需要以下库:

$ rpm -qf /lib64/libX11.so.6 /lib64/libXext.so.6 /lib64/libXss.so.1
libX11-1.6.0-1.fc19.x86_64
libXext-1.3.2-1.fc19.x86_64
libXScrnSaver-1.2.2-5.fc19.x86_64

一旦安装了这些,我将像上面这样编译:

$ gcc xidle.c -o xidle -lX11 -lXext -lXss

您可以看到它可以像这样运行,以报告X将其检测为空闲时间的秒数:

$ while [ 1 ]; do ./xidle ; sleep 2;done
0.005000
1.948000
3.954000
5.959000
7.965000
0.073000   <--- moved the mouse here which resets it
0.035000

使用此可执行文件,您可以将可以执行以下操作的脚本放在一起,监视所报告的空闲时间xidle

$ while [ 1 ]; do idle=$(./xidle); 
    [ $( echo "$idle > 5" | bc ) -eq 0 ] && echo "still < 5" || echo "now > 5"; 
    sleep 2;
done
still < 5
still < 5
still < 5
now > 5
now > 5
still < 5
still < 5
still < 5

上面的代码显示,still < 5直到经过5秒钟的空闲时间,这时才开始说now > 5,这意味着已经过去了5秒钟以上。

注意:您可以将您的代码notify-send 'a'合并到以上示例中。

参考文献


-1

bsd端口(程序包集合)具有一个可以执行此操作的程序:
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"  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.