システムがアイドル状態で再アクティブ化されたときにコマンドを実行します。

システムがアイドル状態で再アクティブ化されたときにコマンドを実行します。

ユーザーが非アクティブ(システムアイドル)状態になったら、コマンドを実行したいと思います。たとえば、

echo "You started to be inactive."

また、ユーザーが再びアクティブにした場合(システムはもはやアイドル状態ではありません):

echo "You started to be active, again."

これにはシェルスクリプトが必要です。タイマー/間隔なしでこれは可能ですか?たぶんシステムイベントですか?

答え1

ArchLinuxフォーラムのこの投稿ユーザーがアイドル状態の期間に関する情報を取得するためにxscreensaverを照会する短いCプログラムが含まれています。これはあなたの要求に非常に近いようです。

#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

それでも定期的なポーリングが必要ですが、必要なすべての操作を実行します。

答え2

これはまさにあなたが要求したものではありませんが、常にbatch- コマンドがあります(通常 - コマンドの特別な呼び出しと - デーモンatで使用されます)。atd

batch負荷平均が特定の制限(通常は1.5ですが起動時に設定できますatd)を下回ると、コマンドを実行するように求められます。特定の時間に実行するのではなく、その時間にジョブを渡し、ロード平均が低下した場合(たとえば、ロード平均が低下した場合)、最初に実行するようにジョブをatプロンプトすることもできます。batch1.5以下では実行されます)。

残念ながら、バッチジョブは最後まで実行され、コンピュータがアイドル状態になっていなくても停止しません。

+++

プログラムのパスに行く必要がある場合(他の回答の場合のようです)、ログインしたユーザーやロード平均を監視するデーモンなどを作成しますatdcrondその後、デーモンはディレクトリでスクリプト/プログラムを実行し、必要に応じてそれを開始/続行または停止(信号を使用)できます。

答え3

bashのTMOUTは、設定された時間(秒)後に対話型セッションを終了します。このメカニズムを使用できます。

適切なトラップを設定するか(テストしない)、bash-logout-scripts(〜/ .bash_logout)を使用してログアウトをキャプチャできます。

これは素晴らしいスーパーユーザーの答えです。

答え4

他の回答がスクリーンセーバーや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)。最初の実行では、/proc/stat自体が解析されるのを待つ必要があるように、cpustatsを変更しないように思われるので、理論的にはうまくいくはずtop -bn2ですtop -bn1

関連情報