一定期間活動がない場合、スクリプトの実行

一定期間活動がない場合、スクリプトの実行

一定期間活動せずにその期間が終了した後に特定のスクリプトを実行する方法を探しています。 「非アクティブ」とは、マウスとキーボードのイベントがないことを意味します。たとえば、私は以下が欲しい:

  1. X分後に最初のスクリプトを実行します。不活性

  2. 2番目のスクリプトは、マウスまたはキーボードでピリオドが中断されたときに実行されます。

メソッドがXシステムに縛られておらず、ターミナルでも動作するならば、これは最高です(Xが起動しないとき)。

ベストアンサー1

必要な機能をサポートする他のプログラミング言語と同様に、少しCマジックを使用してこれを実行できます。あなたがしなければならないことは:

  • すべてのinputイベントデバイスを開く(一致するすべてのデバイス/dev/input/event[0-9]*
  • select(2)これらのデバイスは、適切なタイムアウト(アイドル時間)で入力を待っている間に呼び出されます。
    • タイムアウト:何も起こりませんでした。プログラムを開始してください。
    • 入力が準備されている場合:何が起こるか:実行中のプログラムを終了します。
  • read(2)すべてのデバイスで入力されるため、次のselect(2)呼び出しはすぐには返されません。

C言語の簡単な例は次のとおりです。

#include <sys/select.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    int *fds, ret, i;
    glob_t glob_result;

    /* find all devices matching /dev/input/event[0-9]* */
    ret = glob("/dev/input/event[0-9]*", GLOB_ERR|GLOB_NOSORT|GLOB_NOESCAPE, NULL, &glob_result);
    if (ret)
        err(EXIT_FAILURE, "glob");

    /* allocate array for opened file descriptors */
    fds = malloc(sizeof(*fds) * (glob_result.gl_pathc+1));
    if (fds == NULL)
        err(EXIT_FAILURE, "malloc");

    /* open devices */
    for (i = 0; i < glob_result.gl_pathc; i++) {
        fds[i] = open(glob_result.gl_pathv[i], O_RDONLY|O_NONBLOCK);
        if (fds[i] == -1)
            err(EXIT_FAILURE, "open `%s'", glob_result.gl_pathv[i]);
    }

    fds[i] = -1; /* end of array */

    for (;;) {
        char buf[512];
        struct timeval timeout;
        fd_set readfds;
        int nfds = -1;

        FD_ZERO(&readfds);

        /* select(2) might alter the fdset, thus freshly set it
           on every iteration */
        for (i = 0; fds[i] != -1; i++) {
            FD_SET(fds[i], &readfds);
            nfds = fds[i] >= nfds ? fds[i] + 1 : nfds;

            /* read everything what's available on this fd */
            while ((ret = read(fds[i], buf, sizeof(buf))) > 0)
                continue; /* read away input */
            if (ret == -1 && errno != EAGAIN)
                err(EXIT_FAILURE, "read");
        }

        /* same for timeout, 5 seconds here */
        timeout.tv_sec = 5;    /* FIXME */
        timeout.tv_usec = 0;

        ret = select(nfds, &readfds, NULL, NULL, &timeout);
        if (ret == -1)
            err(EXIT_FAILURE, "select");
        if (ret == 0)
            printf("Timeout: start first script\n");
        } else {
            printf("No timeout: start second script\n");
        }
    }

    return 0;
}

この例では、入力を無期限に待機します。 5秒後に入力が受信されない場合は、「Timeout:...」が印刷されます。入力を受信すると、「No timeout:...」

詳細については、(プロセスを実行して終了したい場合でも)それぞれとをfork(2)参照してください。前述のように、ファイルの実行を許可するすべての言語で十分なので、PythonやRubyなどを使用することもできます。exec(2)kill(2)select(2)

メモ: これは単なる例であり、注意すべき点がさらにあります。たとえば、「timeout」が印刷されます。すべて5秒間、入力が受信されるまで1回ではなく「タイムアウトなし」も表示されます。すべてキー入力/マウス移動。

また、イベントデバイスは明らかな理由で誰も読むことができないため、root実行する必要があります。input

おすすめ記事