Linux 5 dakika boşta kalırsa bir komut yürütün


16

Gibi bir komut yürütmek istiyorum

 notify-send 'a'

Linux makinem 5 dakika boyunca kullanılmadıysa.

Boşta demek istediğim, etkinleştirilen bir ekran koruyucunun "boşta" tanımlamak için kullanacağı şeyle aynı şeyi kastediyorum.


Tamam, ne denedin? Google ne dedi? Ekran koruyucunun bunu nasıl algıladığını bulmaya çalıştınız mı? Lütfen burada soru göndermeden önce arama yapmak için zaman ayırın ve İyi bir soru nasıl sorulur bölümünü okuyun .
terdon

Sadece bir program buldum xautolock, ancak örnek yok

Yanıtlar:


20

xprintidleX boşta kalma süresini bulmak için adlandırılan bir program kullanıyorum , ki bu da ekran koruyucularla aynı veri kaynağını kullanıyor. xprintidlegerçekte artık bir yukarı akışa sahip görünmüyor, ancak Debian paketi canlı ve iyi.

Çok basit bir uygulamadır: Son X etkileşiminden bu yana geçen milisaniye miktarını döndürür:

$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932

(not: altta yatan sistem nedeniyle, ms cinsinden "gerçek" boşta kalma süresinden biraz daha düşük bir değer verir).

Beş dakikalık boşta kalma süresinden sonra belirli bir sekansı çalıştıran bir komut dosyası oluşturmak için bunu kullanabilirsiniz:

#!/bin/sh

# Wanted trigger timeout in milliseconds.
IDLE_TIME=$((5*60*1000))

# Sequence to execute when timeout triggers.
trigger_cmd() {
    echo "Triggered action $(date)"
}

sleep_time=$IDLE_TIME
triggered=false

# ceil() instead of floor()
while sleep $(((sleep_time+999)/1000)); do
    idle=$(xprintidle)
    if [ $idle -ge $IDLE_TIME ]; then
        if ! $triggered; then
            trigger_cmd
            triggered=true
            sleep_time=$IDLE_TIME
        fi
    else
        triggered=false
        # Give 100 ms buffer to avoid frantic loops shortly before triggers.
        sleep_time=$((IDLE_TIME-idle+100))
    fi
done

100 ms'lik sapma, daha önce belirtilen tuhaflıktan kaynaklanır xprintidle, bu da böyle yürütüldüğünde her zaman "gerçek" boşta kalma süresinden biraz daha düşük bir zaman döndürür. Bu ofset olmadan çalışacak ve daha sonra saniyenin onda birine kadar daha doğru olacak, ancak xprintidlebir aralık sona ermeden önceki son milisaniye boyunca kontrolü çılgınca tetikleyecektir . Hiçbir şekilde bir performans domuzu değil, ama bunu yetersiz bulurdum.

Benzer bir yaklaşımı Perl betiğinde (irssi eklentisi) oldukça uzun bir süredir kullandım, ancak yukarıdaki sadece yazıldı ve yazma sırasında birkaç deneme çalıştırması dışında gerçekten test edilmedi.

X içindeki bir terminalde çalıştırarak deneyin. Zaman aşımı test için 5000 ms olarak ayarlanmasını ve nasıl çalıştığını görmek için bilgilendirici çıktı almak için set -xdoğrudan aşağıya eklemenizi öneririm #!/bin/sh.


5

Bu xssstatetür amaçlar için kullanıyorum. Debian veya Ubuntu veya yukarı akıştakisuckless-tools pakette mevcuttur .

Sonra aşağıdaki kabuk betiğini kullanabilirsiniz:

#!/bin/sh

if [ $# -lt 2 ];
then
    printf "usage: %s minutes command\n" "$(basename $0)" 2>&1
    exit 1
fi

timeout=$(($1*60*1000))
shift
cmd="$@"
triggered=false

while true
do
    tosleep=$(((timeout - $(xssstate -i)) / 1000))
    if [ $tosleep -le 0 ];
    then
        $triggered || $cmd
        triggered=true
    else
        triggered=false
        sleep $tosleep
    fi
done

1

İşte derleyebileceğim bir C uygulaması.

$ more xidle.c 
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/scrnsaver.h>

/* Report amount of X server idle time. */
/* Build with- */
/* cc xidle.c -o xidle -lX11 -lXext -lXss */


int main(int argc, char *argv[])
{
    Display *display;
    int event_base, error_base;
    XScreenSaverInfo info;
    float seconds;

    display = XOpenDisplay("");

    if (XScreenSaverQueryExtension(display, &event_base, &error_base)) {
    XScreenSaverQueryInfo(display, DefaultRootWindow(display), &info);

    seconds = (float)info.idle/1000.0f;
    printf("%f\n",seconds);
    return(0);
    }
    else {
    fprintf(stderr,"Error: XScreenSaver Extension not present\n");
    return(1);
    }
}

İnşa edilmesi için birkaç kütüphaneye ihtiyacı var. Fedora 19 sistemimde aşağıdaki kütüphanelere ihtiyacım vardı:

$ rpm -qf /lib64/libX11.so.6 /lib64/libXext.so.6 /lib64/libXss.so.1
libX11-1.6.0-1.fc19.x86_64
libXext-1.3.2-1.fc19.x86_64
libXScrnSaver-1.2.2-5.fc19.x86_64

Bunlar yüklendikten sonra yukarıdaki gibi derledim:

$ gcc xidle.c -o xidle -lX11 -lXext -lXss

X'in aşağıdaki gibi çalıştırarak boşta kalma süresi olarak kaç saniye algıladığını rapor edebildiğini görebilirsiniz:

$ while [ 1 ]; do ./xidle ; sleep 2;done
0.005000
1.948000
3.954000
5.959000
7.965000
0.073000   <--- moved the mouse here which resets it
0.035000

Bu yürütülebilir dosyayı kullanarak, böyle bir şey yapabilen bir komut dosyasını bir araya getirerek rapor edilen boşta kalma süresini izleyebilirsiniz xidle.

$ while [ 1 ]; do idle=$(./xidle); 
    [ $( echo "$idle > 5" | bc ) -eq 0 ] && echo "still < 5" || echo "now > 5"; 
    sleep 2;
done
still < 5
still < 5
still < 5
now > 5
now > 5
still < 5
still < 5
still < 5

Yukarıda, still < 55 saniyelik boşta kalma süresi geçene kadar gösterilir , bu noktada söylemeye başlar now > 5, bu da 5+ saniyenin geçtiği anlamına gelir.

NOT:notify-send 'a' Yukarıdaki örneğe dahil edebilirsiniz .

Referanslar


-1

bsd portları (paketler toplama) bunu yapabilirsiniz bir programı var:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
kullanılabilir mesela burada:
http://distcache.freebsd.org/local- distfiles / yeni / xidle-26052015.tar.bz2

gibi inşa etmek:

 # apt-get install libxss-dev # for include/X11/extensions/scrnsaver.h
 # gcc -o /usr/local/bin/xidle xidle.c -lX11 -lXss

-program'ın execv () öğesine iletildiği için ikili programın tam yolunu içermesi gerektiğini unutmayın.

$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"  
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.