ユーザーが非アクティブ(システムがアイドル状態)になったときにコマンドを実行したい。例えば:
echo "You started to be inactive."
また、ユーザーが再びアクティブになったとき(システムはもうアイドル状態ではありません):
echo "You started to be active, again."
これを行うシェルスクリプトが必要です。これはタイマー/インターバルなしで可能ですか?たぶんいくつかのシステムイベント?
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
これにはまだ定期的なポーリングが必要ですが、必要なことはすべて実行されます...
これはあなたが要求したものではありませんが、常にbatch
- commandがあります(通常、at
- commandの特別な呼び出しとatd
- daemonの使用)。
batch
を使用すると、負荷平均が特定の制限(通常は1.5ですが、atd
の開始時に設定できます)を下回ったときに実行するコマンドをキューに入れることができます。 at
を使用すると、特定の時間に実行されるのではなく、ジョブをキューに入れることもできます。ジョブはその時点でbatch
に配信され、負荷平均が低下したときに最初に実行されます(たとえば、午前2時以降、負荷平均が1.5未満に低下するとすぐに実行されます)。
残念ながら、バッチジョブは最後まで実行され、コンピュータがアイドル状態でなくなっても停止しません。
+++
(他の回答からのように見える)プログラミングルートに行く必要がある場合、私はatd
またはcrond
デーモンに似たものを作ろうと思います。ユーザーおよび/または負荷平均。このデーモンは、特定のディレクトリからスクリプト/プログラムを実行し、必要に応じてそれらを(シグナルで)開始/続行または停止できます。
BashのTMOUTは、設定された秒数後にインタラクティブセッションを終了します。そのメカニズムを使用できます。
適切なトラップを設定するか(私はテストしませんでした)、またはbash-logout-scripts(〜/ .bash_logout)を使用して、ログアウトをキャプチャします。
This スレッドには、キーボードとマウスのアクティビティの検出に基づくいくつかのソリューションがあります。数分おきに開始するcronジョブからxprintidle
を実行します。しかし、彼らが指摘するように、xprintidle
は保守されていないので、Perlモジュールをインストールして、代わりにそれを使用することができます。
$ cpanm X11::IdleTime
...
$ sleep 10; Perl -MX11::IdleTime -le 'print GetIdleTime()'
9
私は、UIが十分にアイドル状態になっていない場合に上部で終了するスクリプトで、cronからポーリングすることでどちらのソリューションも使用します。もちろん、スクリプトにはexport DISPLAY=:0.0
X11と通信するため。
映画を見ているときや、CPUに負荷のかかるタスクを実行しているときは、キーボードとマウスが非アクティブになっている可能性があることに注意してください。
他の回答でスクリーンセーバーや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
しかし、合計時間しか表示されないと思います。ある間隔で結果を比較する必要があります。トップには私自身の問題があります(linux mint 16)。最初の実行では、cpustatsを変更しないようです。まるで/ proc/stat自体の解析を待つ必要があるかのように、したがってtop -bn2
ですが、理論的にはtop -bn1
は動作するはずです。