시스템이 유휴 상태이고 다시 활성화되면 명령을 실행합니다


15

사용자가 비활성화되면 (시스템이 유휴 상태 일 때) 명령을 실행하고 싶습니다. 예를 들면 다음과 같습니다.

echo "You started to be inactive."

또한 사용자가 다시 활성화되면 (시스템이 더 이상 유휴 상태가 아님) :

echo "You started to be active, again."

이 작업을 수행 할 쉘 스크립트가 필요합니다. 타이머 / 간격없이 가능합니까? 어쩌면 일부 시스템 이벤트?


2
실제로 달성하고자하는 것에 대해 좀 더 자세히 설명 할 수 있습니까?
Nils

3
유휴 상태를 어떻게 측정합니까? 컴퓨터와 상호 작용하지 않기 때문에 사용자가 영화를 유휴 상태로보고 있습니까? 원격으로 로그인 한 사용자가 활동 중입니까?
Gilles 'SO- 악마 그만해'

내가 아는 바로는, 시스템은 유휴 , 활성 등의 기본 개념을 가지고 있습니다.
Ionică Bizău

@ IonicăBizău : 실제로는 아닙니다. 시스템의 맥락에서 유휴 는 모든 프로세스가 대기 중이며 '무언가를 기다리고 있음'을 의미합니다. 이것은 현대 시스템에서 자주 발생하고 대부분의 경우에도 해당 될 수 있지만 항상 수행해야 할 작업이 있고 시계를 업데이트하는 경우에는 그렇게 유지되지 않습니다. 유휴 상태 , 특히 질문과 관련하여 유휴 상태 는 시스템보다 사용자의 기능이며 일반적으로 특정 세션에 연결되어있는 것보다 더 중요합니다.
Adaephon

@ 아대 폰 내 개념에서, 사용자가 x 분 동안 컴퓨터에서 어떤 동작 (마우스 이동, 클릭, 키 누름)을 수행하지 않으면 시스템이 유휴 상태 입니다. 사용자가 첫 번째 작업을 수행하면 시스템이 활성화 됩니다. 마우스 버튼 클릭, 이동, 키 누르기 등. 쉘 스크립트를 사용하여 이러한 유휴 * / * 활성 상태 를 감지 할 수 있습니까?
Ionică Bizău

답변:


17

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

여전히 정기 폴링이 필요하지만 필요한 모든 것을 수행합니다 ...


예상대로 작동합니다! +1
Ionică Bizău

당신은 더 많은 가치가 있습니다!
Ionică Bizău

2
자신의 프로그램을 컴파일하고 저장하면 xprintidle대부분의 배포판에서 사용할 수 있으며 정확히 동일한 작업을 수행 할 수 있습니다.
폭동

3

bash의 TMOUT은 설정된 시간 (초) 후에 대화식 세션을 종료합니다. 해당 메커니즘을 사용할 수 있습니다.

해당 트랩 (테스트하지 않음)을 설정하거나 bash-logout-scripts (~ / .bash_logout)를 사용하여 로그 아웃을 캡처합니다.

그 방향에 대한 훌륭한 수퍼 유저 답변입니다.


이것은 $TMOUT몇 초가 지난 후에 사용자가 로그 아웃하는 대신 명령을 실행하는 방법을 다루지 않습니다 .
chepner

답변에 더 많은 정보를 추가 할 수 있습니까? 그것은 여전히 ​​나에게 분명하지 않다 ...
Ionică Bizău

@ chepner 내 답변에 더 자세한 내용을 추가했습니다.
Nils

어느 쪽이든, 이것은 단순히 시간이 지나면 사용자를 로그 아웃합니다. EXIT트랩이나에서 로그 아웃을 중단 할 방법이 없다고 생각 .bash_logout합니다.
chepner

3

이것은 당신이 요구 한 것은 아니지만, 항상 batch-command (보통 -command의 특별한 호출 atatd-daemon 사용)가 있습니다.

batch로드 평균이 특정 한계 (보통 1.5, 그러나 시작시 설정할 수 있음) 아래로 떨어질 때 실행할 명령을 큐 업할 수 있습니다 atd. 로 at이 같은 방법으로 작업을 큐 수도가 아니라 특정 시간에 실행되고있는 이상; 작업은 batch그 시점에 방금 전달 된 후로드 평균이 떨어지면 먼저 실행됩니다 (예 : 오전 2시 이후에로드 평균이 1.5 미만으로 떨어지면 바로 실행됩니다).

불행히도 일괄 작업은 끝까지 실행되며 컴퓨터가 더 이상 유휴 상태가 아닌 경우 중지되지 않습니다.

+++

당신이 (이것은 다른 답변에서 같다) 프로그래밍-경로를 이동해야하는 경우, 나는이 비슷한 만들려고 거라고 생각 atd또는 crond로그인 모니터링 사용자 및 / 또는 부하 평균 데몬. 그런 다음이 데몬은 특정 디렉토리에서 스크립트 / 프로그램을 실행하고 필요에 따라 신호와 함께 시작 / 계속 또는 중지 할 수 있습니다.


이렇게하고 .lock파일을 사용 하면 타이밍 문제를 쉽게 처리 할 수 ​​있습니다.
mikeserv

2

스레드에는 키보드 및 마우스 활동 감지를 기반으로하는 몇 가지 솔루션이 있습니다. xprintidle몇 분마다 시작되는 크론 작업에서 실행 됩니다. 그러나 그들이 지적한대로 xprintidle유지 관리되지 않으므로 Perl 모듈을 설치하고 대신 사용할 수 있습니다.

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

UI가 충분히 유휴 상태가 아닌 경우 상단에서 종료되는 스크립트에서 cron에서 폴링하여 두 솔루션 중 하나를 사용합니다. 물론 스크립트는 export DISPLAY=:0.0X11과 대화하기 위해 필요합니다 .

영화를 보거나 CPU가 많은 작업을 실행할 때는 키보드와 마우스가 작동하지 않을 수 있습니다.


1

다른 답변이 스크린 세이버 또는 bash 유휴 타이머를 사용하거나 .bash_logout에서 실행하는 것과 같이 일종의 시스템 통계를 폴링하지 않고이 작업을 수행하는 방법을 모르겠지만 CPU 사용을 확인하는 아이디어가 있습니다.

여기에는 여전히 n 초마다 폴링이 포함되며 CPU 사용량이 원하는 양보다 적은 경우 실행하려는 모든 것을 스크립팅 할 수 있습니다. 그러나, 당신이 실행하는 것은 CPU 사용량을 증가시킬 수 있지만, 당신의 "것들"에 대해 잘 사용하여 그것을 계산하지 않을 수 있습니다.

다음은 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있지만 총 시간 만 표시한다고 생각하므로 간격에 따라 결과를 비교해야합니다. 탑은 첫 번째 실행에 구문 분석 / PROC / 스탯 자체 따라서 기다려야하는 것처럼, cpustats을 변경하지 않을 것, 나 (리눅스 민트 16)에 대한 자신의 문제입니다 가지고 top -bn2있지만, 이론적으로는 top -bn1작동합니다.


어 ... 진짜? CPU 통계 폴링?
Rolf

그건 그렇고, w사용자 유휴 시간을 보여주는 명령을 폴링 할 수도 있습니다 . -내가 판단하지 않는 한, 그것은 나를 위해, 기계를 잠들고, 전력을 절약하기 위해 유휴 상태를 감지하고 폴링이 그것에 대해 반대하고 싶습니다.
Rolf

@Rolf 소리는 꽤 판단됩니다 ...이 의견은 실제로 제거해야 할 부분이 많지 않으므로 예, 그렇지 않습니까? 어쨌든 다른 답변은 몇 가지 다른 방식으로 유휴 시간을 사용하지만 시스템을 보거나 묻지 않고 유휴를 어떻게 감지 할 수 있습니까?
Xen2050
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.