システムがアイドル状態で、再びアクティブになったときにコマンドを実行する


15

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

echo "You started to be inactive."

また、ユーザーが再びアクティブになったとき(システムはもうアイドル状態ではありません):

echo "You started to be active, again."

これを行うシェルスクリプトが必要です。これはタイマー/インターバルなしで可能ですか?たぶんいくつかのシステムイベント?


2
実際に達成したいことについて、もう少し詳しく説明していただけますか?
ニルス14年

3
怠idleをどのように測定しますか?映画を見ているユーザーはアイドル状態ですか(コンピューターと対話していないため)。リモートでログインしているユーザーはアクティブですか?
ジル 'SO-悪であるのをやめる' 14年

私が知っていることから、システムにはこの概念が組み込まれています:アイドルアクティブなど。これは正しいですか?
IonicăBizău

@IonicăBizău:そうでもない。システムのコンテキストでのアイドルは、すべてのプロセスがスリープしていること、つまり「何かを待っている」ことだけを意味します。これは現代のシステムでは非常に頻繁に発生し、ほとんどの場合に当てはまることもありますが、常に何かを行う必要があり、時計を更新している限り、そのようにはなりません。アイドル状態は、特に質問のコンテキストでは、システムよりもユーザーの機能であり、通常は特定のセッションにリンクされています。
アデフォン14年

@Adaephon [OK]をクリックします。私の概念では、ユーザーがx分間コンピューターでアクション(マウスの移動、クリック、キーの押下)を行わないと、システムはアイドル状態になります。ユーザーが最初のアクションを実行すると、システムがアクティブになります:マウスボタンをクリック、移動、キーを押すなど。それは、これら検出することが可能であるアイドル* / *アクティブなシェルスクリプトを使用して状態を?
IonicăBizău

回答:


17

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

これにはまだ定期的なポーリングが必要ですが、必要なことはすべて行います...


想定通りに動作します!1
IonicăBizău

あなたはより多くのポイントの価値があります!
IonicăBizău

2
独自のプログラムをコンパイルして保存するだけxprintidleで、ほとんどのディストリビューションで使用可能なまったく同じことを行うことができます。
暴動

3

bashのTMOUTは、設定された秒数後にインタラクティブセッションを終了します。そのメカニズムを使用できます。

migthは、対応するトラップを設定する(テストしませんでした)か、bash-logout-scripts(〜/ .bash_logout)を使用してログアウトをキャプチャします。

以下は、その方向への優れたスーパーユーザーの回答です。


これは、$TMOUT数秒が経過した後、ログアウトするのではなく、ユーザーがコマンドを実行する方法には対応していません。
chepner 14年

回答にさらに情報を追加できますか?それは...私にはまだ不明である
IonicăBizău

@chepner回答にさらに詳細を追加しました。
ニルス14年

いずれにせよ、これは単に時間が経過した後にユーザーをログアウトさせるだけです。EXITトラップまたはからログアウトを中止する方法はないと思います.bash_logout
chepner 14年

3

これはあなたが求めたものとはまったく異なりbatchますが、常に-command(通常は-commandの特別な呼び出しと-daemonのat使用atd)があります。

batch負荷平均が特定の制限(通常は1.5ですが、これは開始時に設定できますatd)を下回ったときに実行するコマンドをキューアップできます。atそれはむしろ、特定の時間に実行されてより、このような方法で仕事を頭出しすることも可能です。ジョブはbatchその時点で配信され、負荷平均が低下したときに最初に実行されます(たとえば、午前2時以降に負荷平均が1.5を下回るとすぐに実行されます)。

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

+++

プログラミングルート(他の回答から見える)に行かなければならない場合、ログインユーザーや負荷平均を監視する、atdまたはcrondデーモンに似たものを作成しようと思うと思います。このデーモンは、特定のディレクトリからスクリプト/プログラムを実行し、起動/必要になると(信号で)それらを継続するか停止することができます。


これを実行して.lockファイルを使用すると、タイミングの問題を簡単に処理できます。
mikeserv 14

2

このスレッドには、キーボードとマウスのアクティビティの検出に基づいたいくつかのソリューションがあります。xprintidle数分ごとに開始するcronジョブから実行します。しかし、彼らが指摘してxprintidleいるように、メンテナンスされていないので、Perlモジュールをインストールして、代わりにそれを使用したいかもしれません:

$ cpanm X11::IdleTime
...
$ sleep 10; perl -MX11::IdleTime -le 'print GetIdleTime()'
9

UIが十分にアイドル状態になっていない場合に上部で終了するスクリプトで、cronからポーリングすることにより、どちらのソリューションも使用します。もちろん、スクリプトはexport DISPLAY=:0.0X11と通信するために必要です。

映画を見るとき、またはCPUを大量に消費するタスクを実行するときは、キーボードとマウスが非アクティブになる場合があることに注意してください。


1

他の回答がスクリーンセーバーまたはbashアイドルタイマーを使用するか、.bash_logoutから実行するなど、何らかのシステム統計をポーリングせずにこれを行う方法はわかりませんが、ここではCPU使用率をチェックするアイデアがあります。

これにはn秒ごとのポーリングが含まれ、CPU使用率が選択した量を下回っている場合は、実行するスクリプトを作成できます。ただし、実行するものは何でもCPU使用率を上げる可能性がありますが、「stuff」で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)。最初の実行ではcpustatsを変更しないようです。/proc/stat自体を解析するのを待たなければならないので、top -bn2理論上top -bn1は動作するはずです。


うーん...本当に?CPU統計をポーリングしますか?
ロルフ

ところで、wユーザーのアイドル時間を示すコマンドをポーリングすることもできます。-ところで、私は判断していませんが、私にとっては、アイドル状態を検出して、マシンをスリープ状態にし、電力を節約し、ポーリングはそれに反することです。
ロルフ

@Rolf Soundsはかなり判断しています...そのコメントは実際にはあまり追加されないので、おそらく削除する必要がありますか?とにかく、他の答えはいくつかの異なる方法でアイドル時間を使用しますが、システムを見たり尋ねたりせずにアイドルを検出するにはどうすればよいですか?
Xen2050
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.