Thực thi một lệnh nếu Linux không hoạt động trong 5 phút


16

Tôi muốn thực hiện một lệnh như

 notify-send 'a'

nếu máy Linux của tôi không hoạt động trong 5 phút.

Ở chế độ chờ, ý tôi là điều tương tự trình bảo vệ màn hình được kích hoạt sẽ sử dụng để xác định "không hoạt động".


OK, bạn đã thử những gì? Google đã nói gì? Bạn đã cố gắng tìm hiểu làm thế nào trình bảo vệ màn hình phát hiện điều này? Vui lòng dành thời gian để tìm kiếm trước khi đăng câu hỏi tại đây và đọc qua Cách đặt câu hỏi hay .
terdon

Tôi chỉ tìm thấy một chương trình xautolocknhưng không có ví dụ nào

Câu trả lời:


20

Tôi sử dụng một chương trình được gọi xprintidleđể tìm ra thời gian nhàn rỗi X, mà tôi đoán chắc chắn sử dụng cùng một nguồn dữ liệu như trình bảo vệ màn hình. xprintidledường như không thực sự có dòng ngược nữa, nhưng gói Debian vẫn hoạt động tốt.

Đây là một ứng dụng rất đơn giản: nó trả về số mili giây kể từ lần tương tác X cuối cùng:

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

(lưu ý: do hệ thống cơ bản, nó sẽ liên tục đưa ra một giá trị tính bằng ms thấp hơn một chút so với thời gian nhàn rỗi "thực tế").

Bạn có thể sử dụng điều này để tạo một tập lệnh chạy một chuỗi nhất định sau năm phút không sử dụng thông qua, ví dụ:

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

Độ lệch 100 ms là do cách giải quyết được ghi chú trước đó xprintidlesẽ luôn trả về thời gian thấp hơn một chút so với thời gian nhàn rỗi "thực tế" khi được thực hiện như thế này. Nó sẽ hoạt động mà không có phần bù này, và sau đó sẽ chính xác hơn đến một phần mười giây, nhưng nó sẽ kích hoạt xprintidlekiểm tra một cách điên cuồng trong những mili giây cuối cùng trước khi kết thúc khoảng thời gian. Không phải là một con lợn biểu diễn trong bất kỳ cách nào, nhưng tôi sẽ tìm thấy điều đó không phù hợp.

Tôi đã sử dụng một cách tiếp cận tương tự trong tập lệnh Perl (một plugin irssi) trong một thời gian, nhưng phần trên chỉ mới được viết và chưa thực sự được thử nghiệm ngoại trừ một vài lần chạy thử trong khi viết.

Hãy thử nó bằng cách chạy nó trong một thiết bị đầu cuối trong X. Tôi khuyên bạn nên đặt thời gian chờ là ví dụ 5000 ms để thử nghiệm và thêm set -xtrực tiếp bên dưới #!/bin/shđể có đầu ra thông tin để xem nó hoạt động như thế nào.


5

Tôi sử dụng xssstatecho các mục đích như vậy. Nó có sẵn trong suckless-toolsgói trong Debian hoặc Ubuntu , hoặc ngược dòng .

Sau đó, bạn có thể sử dụng tập lệnh shell sau:

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

Đây là một ứng dụng C mà tôi tìm thấy mà bạn có thể biên dịch.

$ 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ó cần một vài thư viện để xây dựng. Trên hệ thống Fedora 19 của tôi, tôi cần các thư viện sau:

$ 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

Khi chúng được cài đặt, tôi đã biên dịch như trên:

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

Bạn có thể thấy rằng nó có thể báo cáo số giây mà X đang phát hiện là thời gian rảnh bằng cách chạy như vậy:

$ 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

Sử dụng thực thi này, bạn có thể tập hợp một tập lệnh có thể làm một cái gì đó như thế này, theo dõi thời gian nhàn rỗi được báo cáo bởi 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

Ở trên cho thấy still < 5cho đến khi 5 giây thời gian nhàn rỗi đã trôi qua, tại thời điểm nó bắt đầu nói now > 5, có nghĩa là hơn 5 giây đã trôi qua.

LƯU Ý: Bạn có thể kết hợp của bạn notify-send 'a'vào ví dụ trên.

Người giới thiệu


-1

Các cổng bsd (bộ sưu tập gói) có một chương trình có thể làm điều này:
http://man.openbsd.org/OpenBSD-civerse/man1/xidle.1
nó có sẵn, ví dụ: tại đây:
http://distcache.freebsd.org/local- distfiles / novel / xidle-26052015.tar.bz2

xây dựng như:

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

lưu ý rằng chương trình-cần phải chứa đường dẫn đầy đủ đến nhị phân, vì nó được chuyển cho execv ().

$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.