Chạy lệnh khi hệ thống không hoạt động và khi hoạt động trở lại


15

Tôi muốn chạy một lệnh khi người dùng không hoạt động (hệ thống không hoạt động). Ví dụ:

echo "You started to be inactive."

Ngoài ra, khi người dùng hoạt động trở lại (hệ thống không hoạt động nữa):

echo "You started to be active, again."

Tôi cần một kịch bản shell sẽ làm điều này. Điều này có thể mà không có một bộ đếm thời gian / khoảng thời gian? Có lẽ một số sự kiện hệ thống?


2
Bạn có thể đi vào chi tiết sâu hơn một chút về những gì bạn thực sự muốn đạt được?
Nils

3
Làm thế nào để bạn đo lường sự nhàn rỗi? Người dùng đang xem phim nhàn rỗi (vì anh ta không tương tác với máy tính)? Là một người dùng đã đăng nhập hoạt động từ xa?
Gilles 'SO- đừng trở nên xấu xa'

Từ những gì tôi biết, hệ thống có khái niệm tích hợp này: nhàn rỗi , hoạt động , v.v ... Điều này có đúng không?
Ionică Bizău

@ IonicăBizău: Không hẳn. Nhàn rỗi trong bối cảnh của hệ thống sẽ chỉ có nghĩa là tất cả các quy trình đang ngủ, đó là "chờ đợi một cái gì đó". Mặc dù điều này có thể xảy ra khá thường xuyên trên một hệ thống hiện đại và thậm chí có thể là trường hợp thường xuyên, nhưng nó không tồn tại lâu như vậy vì luôn có việc phải làm và nếu nó đang cập nhật đồng hồ. Sự nhàn rỗi , đặc biệt là trong bối cảnh câu hỏi của bạn, là một chức năng của người dùng hơn là hệ thống và thậm chí nó thường được liên kết với một phiên cụ thể.
Adaephon

@Adaephon Ok. Theo khái niệm của tôi, một hệ thống không hoạt động khi người dùng không thực hiện bất kỳ hành động nào (di chuyển chuột, nhấp, nhấn phím) tại máy tính trong x phút. Hệ thống sẽ hoạt động khi người dùng thực hiện hành động đầu tiên: nhấp vào nút chuột, di chuyển nó, nhấn phím và cứ thế. Có thể phát hiện các trạng thái hoạt động nhàn rỗi * / * này bằng cách sử dụng tập lệnh shell?
Ionică Bizău

Câu trả lời:


17

Chuỗi này trên các diễn đàn ArchLinux chứa một chương trình C ngắn truy vấn xscreenaver để biết thông tin người dùng đã nhàn rỗi bao lâu, điều này dường như khá gần với yêu cầu của bạn:

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

Lưu cái này getIdle.cvà biên dịch với

gcc -o getIdle getIdle.c -lXss -lX11

để có được một tập tin thực thi getIdle. Chương trình này in "thời gian nhàn rỗi" (người dùng không di chuyển / nhấp bằng chuột, không sử dụng bàn phím) trong một phần nghìn giây, do đó, một tập lệnh bash xây dựng dựa trên điều này có thể nới lỏng như thế này:

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

Điều này vẫn cần bỏ phiếu thường xuyên, nhưng nó làm mọi thứ bạn cần ...


Hoạt động như được cho là! +1
Ionică Bizău

Bạn có giá trị nhiều điểm hơn!
Ionică Bizău

2
Bạn có thể tiết kiệm cho mình biên dịch chương trình của riêng bạn và chỉ cần sử dụng xprintidle, có sẵn trong hầu hết các bản phân phối và thực hiện chính xác điều tương tự.
Bạo loạn

3

TMOUT trong bash sẽ chấm dứt một phiên tương tác sau số giây đã đặt. Bạn có thể sử dụng cơ chế đó.

Bạn di chuyển bắt đăng xuất bằng cách đặt bẫy theo (tôi không kiểm tra điều đó) hoặc bằng cách sử dụng bash-logout-scripts (~ / .bash_logout).

Đây là một siêu người dùng tốt - trả lời theo hướng đó.


Điều này không giải quyết cách người dùng sẽ thực thi một lệnh, thay vì đăng xuất, sau khi $TMOUTvài giây trôi qua.
chepner

Bạn có thể thêm thông tin vào câu trả lời của bạn? Nó vẫn chưa rõ ràng đối với tôi ...
Ionică Bizău

@chepner Tôi đã thêm một số chi tiết cho câu trả lời của tôi.
Nils

Dù bằng cách nào, điều này chỉ đơn giản là đăng xuất người dùng sau khi hết thời gian. Tôi không nghĩ có bất kỳ cách nào để hủy bỏ đăng xuất, từ một EXITcái bẫy hoặc từ một cái bẫy .bash_logout.
chepner

3

Đây không hoàn toàn là những gì bạn yêu cầu, nhưng luôn có batch-command (thường là một lời gọi đặc biệt của at-command và sử dụng atd-daemon).

batchcho phép bạn đưa ra một lệnh sẽ được chạy khi mức trung bình tải giảm xuống dưới một giới hạn nhất định (thường là 1,5, nhưng điều này có thể được đặt khi bắt đầu atd). Với atnó cũng có thể đưa ra một công việc theo cách thay vì được điều hành tại một thời điểm nhất định; công việc chỉ được chuyển đến batchvào thời điểm đó và lần đầu tiên chạy khi mức trung bình tải giảm xuống (ví dụ: nó chạy ngay khi mức trung bình tải giảm xuống dưới 1,5 vào lúc nào đó sau 2:00 sáng).

Thật không may, một công việc hàng loạt sau đó sẽ chạy đến hết, nó sẽ không dừng lại nếu máy tính không còn hoạt động.

+++

Nếu bạn phải đi theo con đường lập trình (giống như các câu trả lời khác), tôi nghĩ tôi sẽ cố gắng tạo ra một cái gì đó tương tự như atdhoặc cronddaemon, theo dõi người dùng đã đăng nhập và / hoặc tải trung bình. Trình nền này sau đó có thể chạy các tập lệnh / chương trình từ một thư mục nhất định và bắt đầu / tiếp tục hoặc dừng chúng (có tín hiệu) khi cần.


Nếu bạn đã làm điều này và sử dụng .lockcác tập tin, bạn có thể dễ dàng xử lý các vấn đề thời gian.
mikeerv

2

Đây thread có một vài giải pháp dựa trên phát hiện hoạt động bàn phím và chuột. Tôi chạy xprintidletừ một công việc định kỳ bắt đầu cứ sau vài phút. Nhưng như họ chỉ ra xprintidlelà không rõ ràng, vì vậy bạn có thể muốn cài đặt mô-đun Perl và sử dụng thay thế:

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

Tôi sẽ sử dụng một trong hai giải pháp bằng cách bỏ phiếu từ cron, trong một tập lệnh thoát ra ở đầu nếu UI không đủ nhàn rỗi. Tất nhiên kịch bản sẽ cần một export DISPLAY=:0.0để nói chuyện với X11.

Hãy nhớ rằng bàn phím và chuột của bạn có thể không hoạt động khi xem phim hoặc chạy một tác vụ nặng CPU.


1

Tôi không biết cách nào để thực hiện việc này mà không bỏ phiếu một số loại thống kê hệ thống, như các câu trả lời khác sử dụng bộ bảo vệ màn hình hoặc bộ đếm thời gian nhàn rỗi hoặc chạy từ .bash_logout, nhưng đây là một ý tưởng để kiểm tra mức độ sử dụng CPU.

Điều này vẫn sẽ liên quan đến việc bỏ phiếu cứ sau n giây và nếu mức sử dụng CPU của bạn dưới bất kỳ số tiền nào bạn chọn thì bạn có thể viết kịch bản bất cứ điều gì bạn muốn chạy. Tuy nhiên, bất cứ điều gì bạn chạy đều có thể tăng mức sử dụng CPU, nhưng bạn có thể sử dụng tốt "công cụ" của mình để không tính nó.

Đây là tập lệnh thử nghiệm bằng cách sử dụng hàng đầu, nhưng thay vào đó bạn có thể sử dụng mpstat hoặc kiểm tra mức trung bình tải?

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

Đó chỉ là một kịch bản tôi đã tập hợp lại để kiểm tra việc đọc nhàn rỗi từ đầu. Bạn có thể phân tích cú pháp /proc/statnhưng tôi nghĩ rằng nó chỉ hiển thị tổng số lần và bạn cần so sánh kết quả trong một khoảng thời gian. Top có vấn đề riêng đối với tôi (linux mint 16), trong lần chạy đầu tiên, nó dường như không bao giờ thay đổi cpustats, như thể nó phải chờ để phân tích / Proc / stat, do đó, top -bn2trên lý thuyết top -bn1nên hoạt động.


Ừ ... thật sao? Bỏ phiếu thống kê CPU?
Rolf

Nhân tiện, bạn cũng có thể thăm dò wlệnh hiển thị thời gian rảnh của người dùng. - Bằng cách này, tôi không phán xét, chỉ là đối với tôi, tôi muốn phát hiện nhàn rỗi để đặt máy ngủ, để dự phòng năng lượng và bỏ phiếu đi ngược lại điều đó.
Rolf

@Rolf Nghe có vẻ khá phán xét ... vì nhận xét đó thực sự không thêm nhiều nên có lẽ nên xóa đi, đúng không? Dù sao, các câu trả lời khác sử dụng thời gian nhàn rỗi theo một số cách khác nhau, nhưng làm thế nào bạn có thể phát hiện nhàn rỗi mà không cần nhìn / hỏi hệ thống?
Xen2050
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.