Sistem boştayken ve tekrar aktif olduğunda bir komut çalıştır


15

Kullanıcı devre dışı kaldığında bir komut çalıştırmak istiyorum (sistem boşta). Örneğin:

echo "You started to be inactive."

Ayrıca, kullanıcı tekrar aktif hale geldiğinde (sistem artık boşta değil):

echo "You started to be active, again."

Bunu yapacak bir kabuk komut dosyasına ihtiyacım var. Zamanlayıcı / aralık olmadan bu mümkün müdür? Belki bazı sistem olayları?


2
Gerçekte neyi başarmak istediğinizle ilgili biraz daha derin ayrıntılara girebilir misiniz?
Nils

3
Tembelliği nasıl ölçersiniz? Bir kullanıcı bir filmi izliyor mu (bilgisayarla etkileşime girmediği için)? Uzaktan oturum açan bir kullanıcı etkin mi?
Gilles 'SO- kötü olmayı bırak'

Bildiğim kadarıyla, sistem şu yerleşik konsepte sahiptir: boş , aktif vb. Bu doğru mu?
Ionică Bizău

@ IonicăBizău: Pek değil. Sistem bağlamında boşta kalmak , yalnızca tüm süreçlerin uyuduğu, yani bir şey beklediği anlamına gelir. Bu, modern bir sistemde oldukça sık olabilse ve çoğu zaman böyle olsa da, her zaman yapılacak bir şey olduğu ve saati güncellediği takdirde bu şekilde kalmaz. Tembellik , özellikle sorunuz bağlamında, kullanıcının sistemden daha fazla bir işlevidir ve hatta genellikle belirli bir oturuma bağlı olduğundan daha fazladır.
Adaephon

@Adaephon Tamam. Benim kavramımda, kullanıcı bilgisayarda x dakika hiçbir işlem yapmadığında (fare hareketi, tıklama, tuşa basma) bir sistem boşta kalır . Kullanıcı ilk eylemi gerçekleştirdiğinde sistem etkinleşir : bir fare düğmesini tıklar, hareket ettirir, bir tuşa basar vb. Bu boş * / * aktif durumlarını kabuk betiği kullanarak tespit etmek mümkün müdür ?
Ionică Bizău

Yanıtlar:


17

ArchLinux forumlarındaki bu iş parçacığı , kullanıcının ne kadar süre boşta kaldığı hakkında bilgi almak için xscreensaver'ı sorgulayan kısa bir C programı içerir, bu gereksinimlerinize oldukça yakın görünmektedir:

#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);
}

Bunu farklı kaydet getIdle.cve derle

gcc -o getIdle getIdle.c -lXss -lX11

yürütülebilir bir dosya almak için getIdle. Bu program milisaniye içinde "boşta kalma süresi" (kullanıcı fare ile hareket etmiyor / tıklamıyor, klavye kullanmıyor) yazdırıyor, bu nedenle üzerine kurulu bir bash betiği şöyle görünebilir:

#!/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

Bu hala düzenli oylamaya ihtiyaç duyuyor, ancak ihtiyacınız olan her şeyi yapıyor ...


Sözde çalışıyor! +1
Ionică Bizău

Daha fazla puan değer!
Ionică Bizău

2
Kendinizi kendi programınızı derleyerek kurtarabilir ve sadece xprintidlebirçok dağıtımda bulunan ve tamamen aynı şeyi yapan kullanabilirsiniz.
Riot

3

Bass içindeki TMOUT, belirlenen saniye sayısından sonra etkileşimli bir oturumu sonlandıracaktır. Bu mekanizmayı kullanabilirsiniz.

Uygun bir tuzak ayarlayarak (bunu test etmedim) veya bash-logout-komut dosyalarını (~ / .bash_logout) kullanarak oturumu kapatırsınız.

İşte bu yönde iyi bir süper kullanıcı cevabı.


Bu, kullanıcının $TMOUTsaniye geçtikten sonra oturumu kapatmak yerine bir komutu nasıl yürüteceğini ele almaz .
Chepner

Cevabınıza daha fazla bilgi ekleyebilir misiniz? Benim için hala belirsiz ...
Ionică Bizău

@chepner Cevabıma biraz daha ayrıntı ekledim.
Nils

Her iki durumda da, bu süre dolduktan sonra kullanıcının oturumunu kapatır. Bir EXITtuzaktan ya da birinden, oturumu kapatmanın herhangi bir yolu olduğunu düşünmüyorum .bash_logout.
chepner

3

Bu tam olarak istediğin şey değil, ama her zaman batch-komut (genellikle -komutun özel bir çağrılması ve at-daemon'u kullanma atd) vardır.

batchyük ortalaması belirli bir sınırın altına düştüğünde çalıştırılacak bir komutu işaretlemenizi sağlar (genellikle 1.5, ancak bu başlangıç ​​sırasında ayarlanabilir atd). İle atbu şekilde bir iş işareti açısından da mümkün olduğunu ziyade belirli bir zamanda koşmak olmaktan daha; iş batcho anda teslim edilir ve ilk olarak yük ortalaması düştüğünde çalışır (ör. yük ortalaması 2: 00'den sonra bir süre 1.5 altına düştüğünde çalışır).

Ne yazık ki bir toplu iş daha sonra sonuna kadar çalışacak, bilgisayar artık boşta değilse, durmayacaktır.

+++

Programlama yoluna (diğer cevaplardan göründüğü gibi) gitmeniz gerekiyorsa, giriş yapan kullanıcıları ve / veya yük ortalamasını izleyen atdveya crondcinlere benzer bir şey yapmaya çalışacağımı düşünüyorum . Bu arka plan programı daha sonra belirli bir dizinden komut dosyalarını / programları çalıştırabilir ve gerektiğinde bunları başlatabilir / durdurabilir veya durdurabilir (sinyallerle).


Bunu yaptıysanız ve .lockdosyaları kullandıysanız, zamanlama sorunlarını kolayca halledebilirsiniz.
mikeserv

2

Bu iş parçacığının klavye ve fare etkinliğini algılamaya dayalı birkaç çözümü vardır. Ben koşmak xprintidlebirkaç dakikada başlayan bir cron işi dan. Ancak işaret ettikleri gibi xprintidle, Perl modülünü kurmak ve bunu kullanmak isteyebilirsiniz:

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

Her iki çözümü de, kullanıcı arayüzü yeterince boş değilse üstte çıkan bir komut dosyasında cron'dan yoklama yaparak kullanırdım. Tabii ki senaryo export DISPLAY=:0.0X11 ile konuşmak için bir gerekir .

Bir film izlerken veya yoğun bir CPU görevi yürütürken klavyeniz ve fareniz etkin olmayabilir.


1

Diğer cevaplar bir ekran koruyucu veya bash boşta zamanlayıcı kullanın ya da .bash_logout çalıştıran gibi bazı sistem istatistikleri yoklama olmadan bunu yapmanın bir yolunu bilmiyorum, ama burada CPU kullanımını kontrol etmek için bir fikir.

Bu hala her n saniyede bir yoklamayı içerir ve CPU kullanımınız seçtiğiniz herhangi bir miktarın altındaysa, çalıştırmak istediğiniz her şeyi komut dosyası olarak yazabilirsiniz. Ancak, çalıştırdığınız her şey CPU kullanımını artırabilir, ancak "işlerinizde" saymamak için iyi kullanabilirsiniz.

İşte top kullanarak bir test komut dosyası, ancak bunun yerine mpstat kullanabilir veya bunun yerine yük ortalamalarını kontrol edebilirsiniz?

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

Bu sadece boşta yukarıdan okumayı test etmek için birlikte attığım bir senaryo. Ayrıştırabilirsiniz, /proc/statancak bunun yalnızca toplam süreleri gösterdiğini ve sonuçları bir aralıkta karşılaştırmanız gerektiğini düşünüyorum. Topun benim için kendi sorunu var (linux nane 16), ilk çalışmada cpustats'ı asla değiştirmiyor gibi görünüyor, sanki ayrıştırmak / proc / stat'i beklemek zorunda gibi görünüyor, bu yüzden top -bn2teoride top -bn1çalışmalı.


Ah ... gerçekten mi? CPU istatistiklerini yoklama?
Rolf

Bu arada, wkullanıcının boşta kalma süresini gösteren komutu da yoklayabilirsiniz. - Bu arada yargılamıyorum, sadece benim için, makineyi uyutmak, yedek güç vermek için boşta algılamak istiyorum ve oylama buna karşı çıkıyor.
Rolf

@Rolf Oldukça yargılayıcı geliyor ... Bu yorum gerçekten fazla bir şey eklemediğinden muhtemelen kaldırılması gerekiyor, değil mi? Her neyse, diğer cevaplar boşta kalma süresini birkaç farklı şekilde kullanır, ancak sisteme bakmadan / sormadan boşta nasıl tespit edebilirsiniz?
Xen2050
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.