일시 중단을 금지하는 방법은 무엇입니까?


10

나는 이것에 대해 조금 검색했고 도움이되는 것을 찾을 수없는 것 같습니다.

30 분 동안 활동이 없으면 Ubuntu 12.10을 실행하는 PC가 일시 중지되도록 설정되어 있습니다. 나는 그것을 바꾸고 싶지 않으며, 그것은 대부분의 시간에 효과적입니다.

내가하고 싶은 것은 특정 응용 프로그램이 실행중인 경우 자동 일시 중단을 비활성화하는 것입니다. 어떻게해야합니까?

지금까지 찾은 가장 가까운 것은 쉘 스크립트를 추가 /usr/lib/pm-utils/sleep.d하여 응용 프로그램이 실행 중인지 확인하고 일시 중지를 방지해야 함을 나타내는 1을 반환하는 것입니다. 그러나 30 분 후에 다시 시도하지 않고 시스템이 자동으로 일시 중지되는 것처럼 보입니다. (알 수있는 한, 마우스를 움직이면 타이머가 다시 시작됩니다.) 응용 프로그램이 몇 시간 후에 완료 될 가능성이 높으며 사용하지 않으면 PC가 자동으로 일시 중지됩니다 그 시점에서 . (응용 프로그램이 완료되면 pm-suspend에 전화를 걸고 싶지 않습니다.)

이것이 가능한가?

편집 : 아래 의견 중 하나에서 언급했듯이 실제로 원하는 것은 내 PC가 NFS를 통해 파일을 제공 할 때 일시 중단을 방지하는 것이 었습니다. NFS 부분을 해결하는 방법을 이미 알고 있었기 때문에 질문의 "일시 중단"부분에 집중하고 싶었습니다. 답 중 하나에 주어진 'xdotool'아이디어를 사용하여 몇 분마다 cron에서 실행되는 다음 스크립트를 생각해 냈습니다. 화면 보호기가 시작되는 것을 막기 때문에 이상적이지는 않지만 작동합니다. '카페인'이 나중에 일시 중단을 올바르게 다시 활성화하지 않는 이유를 살펴 봐야 할 것입니다. 어쨌든, 이것은 효과가있는 것처럼 보이므로 다른 사람이 관심이있는 경우 여기에 포함시킵니다.

#!/bin/bash

# If the output of this function changes between two successive runs of this
# script, we inhibit auto-suspend.
function check_activity()
{
    /usr/sbin/nfsstat --server --list
}

# Prevent the automatic suspend from kicking in. 
function inhibit_suspend()
{
    # Slightly jiggle the mouse pointer about; we do a small step and
    # reverse step to try to stop this being annoying to anyone using the
    # PC. TODO: This isn't ideal, apart from being a bit hacky it stops
    # the screensaver kicking in as well, when all we want is to stop
    # the PC suspending. Can 'caffeine' help?
    export DISPLAY=:0.0
    xdotool mousemove_relative --sync --  1  1
    xdotool mousemove_relative --sync -- -1 -1
}

LOG="$HOME/log/nfs-suspend-blocker.log"
ACTIVITYFILE1="$HOME/tmp/nfs-suspend-blocker.current"
ACTIVITYFILE2="$HOME/tmp/nfs-suspend-blocker.previous"

echo "Started run at $(date)" >> "$LOG"
if [ ! -f "$ACTIVITYFILE1" ]; then
    check_activity > "$ACTIVITYFILE1"
    exit 0;
fi

/bin/mv "$ACTIVITYFILE1" "$ACTIVITYFILE2"
check_activity > "$ACTIVITYFILE1"

if cmp --quiet "$ACTIVITYFILE1" "$ACTIVITYFILE2"; then
    echo "No activity detected since last run" >> "$LOG"
else
    echo "Activity detected since last run; inhibiting suspend" >> "$LOG"
    inhibit_suspend
fi

편집 2 : 위의 스크립트는 작동하지만 아래의 다른 의견 덕분에 이제이 스크립트 쌍을 사용하고 있습니다.이 스크립트는 일시 중단을 억제하면서 화면 보호기가 시작되도록하는 이점이 있습니다. 첫 번째는 /usr/lib/pm-utils/sleep.d/000nfs-inhibit이며, 금지 파일이있는 경우 일시 중지 시도를 방지합니다.

#!/bin/sh

LOG="/home/zorn/log/nfs-suspend-blocker.log"
INHIBITFILE="/home/zorn/tmp/nfs-suspend-blocker.inhibit"

echo "$0: Started run at $(date), arguments: $*" >> "$LOG"
if [ "$1" = "suspend" ] && [ -f "$INHIBITFILE" ]; then
    echo "$0: Inhibiting suspend" >> "$LOG"
    exit 1
fi
exit 0

두 번째는 이전 nfs-suspend-blocker 스크립트의 수정 된 버전이며 여전히 cron에서 실행해야합니다. 이제 아래 의견에 요약 된 전략을 따릅니다.

#!/bin/bash

# This works in tandem with /usr/lib/pm-utils/sleep.d/000nfs-inhibit, which
# will prevent a suspend occurring if $INHIBITFILE is present. Once it prevents
# a suspend, it appears that it requires some "user activity" to restart the
# timer which will cause a subsequent suspend attempt, so in addition to
# creating or removing $INHIBITFILE this script also jiggles the mouse after
# removing the file to restart the timer.

# If the output of this function changes between two successive runs of this
# script, we inhibit auto-suspend.
function check_activity()
{
    /usr/sbin/nfsstat --server --list
}

# Slightly jiggle the mouse pointer about; we do a small step and reverse step
# to try to stop this being annoying to anyone using the PC.
function jiggle_mouse()
{
    export DISPLAY=:0.0
    xdotool mousemove_relative --sync --  1  1
    xdotool mousemove_relative --sync -- -1 -1
}

LOG="$HOME/log/nfs-suspend-blocker.log"
ACTIVITYFILE1="$HOME/tmp/nfs-suspend-blocker.current"
ACTIVITYFILE2="$HOME/tmp/nfs-suspend-blocker.previous"
INHIBITFILE="$HOME/tmp/nfs-suspend-blocker.inhibit"

echo "$0: Started run at $(date)" >> "$LOG"
if [ ! -f "$ACTIVITYFILE1" ]; then
    check_activity > "$ACTIVITYFILE1"
    exit 0;
fi

/bin/mv "$ACTIVITYFILE1" "$ACTIVITYFILE2"
check_activity > "$ACTIVITYFILE1"

if cmp --quiet "$ACTIVITYFILE1" "$ACTIVITYFILE2"; then
    echo "$0: No activity detected since last run" >> "$LOG"
    if [ -f "$INHIBITFILE" ]; then
            echo "$0: Removing suspend inhibit file and jiggling mouse" >> "$LOG"
            /bin/rm "$INHIBITFILE"
            jiggle_mouse
    fi
else
    echo "$0: Activity detected since last run; inhibiting suspend" >> "$LOG"
    touch "$INHIBITFILE"
fi

질문을 복잡하게 만드는 대신 두 가지 해결책을 아래의 대답으로 문제에 넣어야합니다.
Cas

답변:


8

컴퓨터를 깨우는 프로그램은 Caffeine 입니다. 원래 코드가 호출 될 때 카페인을 호출하도록 .bash_aliases 파일을 만들 것입니다.

alias newname="origcode && caffeine"

컴퓨터를 깨우려는 코드에 따라 다른 코드가 중지 될 때 카페인을 죽이는 것을 포함하는 사용자 지정 스크립트를 만들어야합니다. 특정 코드에 대한 자세한 내용이 도움이 될 것입니다.

업데이트 : 더 간단한 방법은 xdotool 을 실행하는 것 입니다 sudo apt-get install xdotool. 대상 코드가 열릴 때 호출되는 스크립트를 작성한 다음 sleep29 분 동안 명령을 사용한 다음 xdotool key a컴퓨터를 깨우기 위해 임의의 것을 실행할 수 있습니다.


2
xdo의 경우 본질적으로 무언가를하지 않는 키를 선택하는 것이 좋습니다. 예를 들어, Shift 키를 누르면 활성 창에서 입력하지 않고 화면을 깨 웁니다.
Oli

1
감사합니다. 원래 질문에 의도적으로 약간의 세부 사항을 숨기고있었습니다. 내 명시 적으로하고 싶은 것은 내 미디어 센터가 액세스하는 동안 PC (NFS를 통해 미디어 콘텐츠를 제공하는)를 중지하는 것입니다. 이 문제를 구체적으로 해결하는 방법을 알고 있다면 카페인을 통해 작동 할 수있는 몇 가지 방법을 볼 수 있습니다 (예 : 미디어 센터는 10 분마다 내 PC에 ssh하고 잠자는 쉘 스크립트를 실행합니다) 15 분 동안).
Zorn

1
나는 카페인을 시도했지만 실행중인 프로그램이 사라지면 카페인 출력에 일시 중단이 더 이상 억제되지 않는다고 말하지만 비 활동 기간의 두 배로 남겨 두었습니다. xdo 경로가 훨씬 더 편리 할 것 같지만 먼저 시도해 보겠습니다. PS 주석에 개행을 삽입하는 방법이 있습니까?!
Zorn

5

만약

  1. /usr/lib/pm-utils/sleep.d의 스크립트는 응용 프로그램이 실행 중인지 확인하고 1을 반환하여 일시 중단을 방지해야 함을 나타냅니다.
  2. 타이머를 다시 시작하는 마우스를 움직여 "시스템이 30 분 후에 다시 시도하지 않고 자동으로 일시 중단하는 문제"가 해결됩니다.

그렇다면 응용 프로그램이 끝난 후 마우스 포인터를 움직이지 않는 이유는 무엇입니까?

요약하면 다음과 같습니다.

  1. sleep.d를 사용하여 시스템이 일시 중지되지 않도록하십시오.
  2. 마우스를 한 번 흔들리는 스크립트를 작성하십시오.
  3. '장기 실행 스크립트 및 마우스 흔들기'호출

이것은 스크린 세이버를 방해하지 않습니다.

유일한 문제점은 시스템이 일시 중단 될 때 프로세스가 종료 된 후 30 분이 소요된다는 것입니다. 이것은 'EDIT'솔루션에도 해당됩니다.

추신 :이 페이지에서 xdotool을 배울 때 비슷한 문제에 대한 해결책을 찾고있었습니다. 감사합니다. 도움이 되었기를 바랍니다.


독창적입니다, 감사합니다! 나는 이번 주말에 그것을 갈 것이다.
Zorn

pm-utils도움 이되는 힌트 . 주 패키지가 그 pm-utils디렉토리 자체가 패키지가 설치되지 않은 경우에도있을 수 있습니다 - 작업이 순서대로 설치해야합니다.
krlmlr

1

EDIT 2는 차단 파일 제거시 화면 보호기가 시작되고 자동 일시 중지 서비스를 다시 시작하지만 위에서 언급 한 것처럼 시스템이 일시 중단 될 때 파일이 제거 된 후 30 분이 걸립니다.

하나의 가능한 해결책은 내장 된 자동 화면 보호기 및 자동 일시 중단 기능을 비활성화하고 자체적으로 구현하고 필요에 따라 타이머의 동작을 선택하는 것입니다. xprintidle 명령(이를 설치해야 할 수도 있음) 키보드 또는 마우스 작업이 없었던 시간 (밀리 초)을 인쇄합니다. 이것은 몇 가지 가능성을 열어줍니다. 파이썬에서 다음과 같은 비활성 관리자를 구현했습니다 (너무 많은 bash 스크립터는 아닙니다). 스크린 세이버 및 자동 일시 중지에 대한 명령 설정, 시간 초과 및 파일 금지 (잠금이라고 함) 기능이 있습니다. 또한 금지 파일을 제거 할 때 비활성 타이머를 다시 시작할지 여부를 선택할 수있는 옵션이 있습니다 (일시 중지 및 화면 보호기의 동작이 다를 수 있음). 메모에서 사용법을 명확하게하려고했지만 분명하지 않은 경우 물어보십시오.

#!/usr/bin/python

#Notes:##################

#   1. All TIMEOUTs are specified in seconds
#   2. 0 or negative TIMEOUT disables a particular action.
#   3. If an actionCOMMAND (like pm-suspend) requires 'sudo'ing, make them 'sudo'able without password. Alternatively, you may run this script in sudo mode, and make this script sudoable without password. /ubuntu/159007/specific-sudo-commands-without-password
#   4. 'action'_timer_starts_... option: True - if a lock file is created and then removed, inactivity timer (for that action) restarts at the time of deletion of lock. False - doesn't restart.
#   5. screensaverCOMMAND can be screen-lock (security) or screen-off (power saving) or both. To do both, but at different times (I can't see any reason to do so) extend this script from two actions (screensaver, autosuspend) to three (screen-lock, screen-off, autosuspend).

#########################

import os
import time
import threading
import subprocess

HOME = os.getenv('HOME') + '/'

#Configuration###########

screensaverCOMMAND = "gnome-screensaver-command --lock && xset -display :0.0 +dpms dpms force off"
autosuspendCOMMAND = "gnome-screensaver-command --lock && sudo pm-suspend"

screensaverTIMEOUT = 10*60
autosuspendTIMEOUT = 20*60

screensaverLOCK = HOME + ".inactivitymanager/screensaverLOCK"
autosuspendLOCK = HOME + ".inactivitymanager/autosuspendLOCK"

screensaver_timer_starts_only_after_lockfile_is_deleted = False
autosuspend_timer_starts_only_after_lockfile_is_deleted = False

#########################

def stayOn():
    print "inactivitymanager is running..."
    try:
        while True:
            time.sleep(10)
    except:
        print "Closed."

class inactivity_action(threading.Thread):
    def __init__(self, command, timeout, lock, timer_starts_blah):
        threading.Thread.__init__(self)
        self.daemon = True
        self.command = command
        self.timeout = timeout
        self.lock = lock
        self.timer_starts_blah = timer_starts_blah
    def run(self):
        if not(self.timer_starts_blah):
            while True:
                try:
                    while True:
                        time.sleep(1)
                        f = open(self.lock, 'r')
                        f.close()
                except IOError:
                    xidletime = int(subprocess.Popen('xprintidle', stdout = subprocess.PIPE).communicate()[0])/1000
                    if xidletime > self.timeout:
                        os.system(self.command)
                    else:
                        time.sleep(self.timeout - xidletime + 2)
        else:
            lockremovetime = 0
            while True:
                lockdetected = False
                try:
                    while True:
                        time.sleep(1)
                        f = open(self.lock, 'r')
                        f.close()
                        lockdetected = True
                except IOError: #Will enter this section if/when lockfile is/becomes absent
                    xidletime = int(subprocess.Popen('xprintidle', stdout = subprocess.PIPE).communicate()[0])/1000
                    if lockdetected:
                        lockremovetime = int(time.time())
                    timesincelockremove = int(time.time()) - lockremovetime
                    if min(xidletime, timesincelockremove) > self.timeout:
                        os.system(self.command)

if screensaverTIMEOUT > 0:
    inactivity_screensaver = inactivity_action(screensaverCOMMAND, screensaverTIMEOUT, screensaverLOCK, screensaver_timer_starts_only_after_lockfile_is_deleted)
    inactivity_screensaver.start()

if autosuspendTIMEOUT > 0:
    inactivity_autosuspend = inactivity_action(autosuspendCOMMAND, autosuspendTIMEOUT, autosuspendLOCK, autosuspend_timer_starts_only_after_lockfile_is_deleted)
    inactivity_autosuspend.start()

stayOn()

용법:

  1. inactivitymanager &홈 디렉토리의 .profile 또는 .xsessionrc에 추가 하십시오 (어느 것이 효과가 있는지 참조하십시오. 둘 다 추가하지 마십시오. 그렇지 않으면이 스크립트의 두 인스턴스가 동시에 처리됩니다. 주류 구현은 사용자 정의 구현보다 우선합니다.
  2. xprintidle을 설치해야 할 수도 있습니다.

금지 파일이 도착하는 방법은 현재 사용자의 상상력에 맡겨져 있습니다 (이 데몬을 구현하도록 유도하면이 답변의 편집에 넣습니다). 물론 귀하 (OP)가 귀하의 사례를 해결했습니다. 둘 이상의 프로세스에 대해 일시 중단을 방지하려고 할 때 피해야 할 함정은 한 프로세스가 종료되고 다른 프로세스가 여전히 실행 중일 때 잠금 파일을 삭제하는 것입니다. 또는 일부 파일이 특정 디렉토리 (잠금 디렉토리)에있는 경우 일시 중단을 방지하기 위해 스크립트를 약간 편집 할 수 있습니다. 이런 식으로 각 프로세스는 자체 잠금 파일을 가질 수 있습니다.

노트:

  1. 이 스크립트는 프로세서와 메모리에서 매우 밝습니다. 그러나 코드에서 time.sleep (1)을 제거하면 문제가 발생할 수 있습니다.
  2. pm-suspend에는 sudo 권한이 필요합니다. 비밀번호를 체크 아웃하지 않고 pm-suspend하려면 비밀번호없이 특정 sudo 명령을 실행하려면 어떻게합니까? . 또는이 스크립트를 sudo 모드에서 실행하고 비밀번호없이이 스크립트를 sudoable로 만들 수 있습니다 (루트로 스크립트를 실행하는 경우 문제가되지 않음)
  3. 시간 초과가 ~ 10 초 미만으로 설정되면 스크립트가 문제를 일으킬 수 있습니다 (문제가 시작되는 위치를 정확히 5 미만으로 확인해야합니다). 시스템 리소스를 희생하여 time.sleep (1)을 제거하여 처리 할 수 ​​있습니다. 아무도 이것을 필요로 할 것이라고 생각하지 마십시오.
  4. 우리는 타이머를 다루기 때문에 마우스 흔들림이 필요하지 않습니다!
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.