ユーザーが非アクティブになった(システムがアイドル状態になった)ときにコマンドを実行したい。例えば:
echo "You started to be inactive."
また、ユーザーが再びアクティブになったとき(システムはもうアイドル状態ではありません):
echo "You started to be active, again."
これを行うシェルスクリプトが必要です。これはタイマー/インターバルなしで可能ですか?たぶんいくつかのシステムイベント?
ユーザーが非アクティブになった(システムがアイドル状態になった)ときにコマンドを実行したい。例えば:
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
これにはまだ定期的なポーリングが必要ですが、必要なことはすべて行います...
xprintidle
で、ほとんどのディストリビューションで使用可能なまったく同じことを行うことができます。
bashのTMOUTは、設定された秒数後にインタラクティブセッションを終了します。そのメカニズムを使用できます。
migthは、対応するトラップを設定する(テストしませんでした)か、bash-logout-scripts(〜/ .bash_logout)を使用してログアウトをキャプチャします。
$TMOUT
数秒が経過した後、ログアウトするのではなく、ユーザーがコマンドを実行する方法には対応していません。
EXIT
トラップまたはからログアウトを中止する方法はないと思います.bash_logout
。
これはあなたが求めたものとはまったく異なりbatch
ますが、常に-command(通常は-commandの特別な呼び出しと-daemonのat
使用atd
)があります。
batch
負荷平均が特定の制限(通常は1.5ですが、これは開始時に設定できますatd
)を下回ったときに実行するコマンドをキューアップできます。at
それはむしろ、特定の時間に実行されてより、このような方法で仕事を頭出しすることも可能です。ジョブはbatch
その時点で配信され、負荷平均が低下したときに最初に実行されます(たとえば、午前2時以降に負荷平均が1.5を下回るとすぐに実行されます)。
残念ながら、バッチジョブは最後まで実行され、コンピューターがアイドル状態でなくなっても停止しません。
+++
プログラミングルート(他の回答から見える)に行かなければならない場合、ログインユーザーや負荷平均を監視する、atd
またはcrond
デーモンに似たものを作成しようと思うと思います。このデーモンは、特定のディレクトリからスクリプト/プログラムを実行し、起動/必要になると(信号で)それらを継続するか停止することができます。
.lock
ファイルを使用すると、タイミングの問題を簡単に処理できます。
このスレッドには、キーボードとマウスのアクティビティの検出に基づいたいくつかのソリューションがあります。xprintidle
数分ごとに開始するcronジョブから実行します。しかし、彼らが指摘して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使用率を上げる可能性がありますが、「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
は動作するはずです。
w
ユーザーのアイドル時間を示すコマンドをポーリングすることもできます。-ところで、私は判断していませんが、私にとっては、アイドル状態を検出して、マシンをスリープ状態にし、電力を節約し、ポーリングはそれに反することです。