Як інгібувати призупинення тимчасово?


10

Я трохи пошукав це, і не можу знайти щось корисне.

У мене на комп'ютері під керуванням Ubuntu 12.10 налаштовано призупинення роботи після 30 хвилин бездіяльності. Я не хочу цього змінювати, це працює чудово більшу частину часу.

Що я хочу зробити - це відключити автоматичне призупинення роботи, якщо працює певна програма. Як я можу це зробити?

Найближче, що я знайшов поки що, - це додати скрипт оболонки, у /usr/lib/pm-utils/sleep.dякому перевіряється, чи працює програма та повертає 1, щоб вказати, що призупинення потрібно запобігти. Але схоже, що система потім відмовляється від зупинки автоматично, замість того, щоб повторити спробу ще через 30 хвилин. (Наскільки я можу сказати, якщо я переміщу мишку, вона знову перезапустить таймер.) Цілком ймовірно, що програма закінчиться через пару годин, і я вважаю за краще, щоб мій ПК автоматично призупинився, якщо я не використовую це в той момент . (Тому я не хочу додавати дзвінок у вечірню зупинку, коли програма закінчиться.)

Чи можливо це?

EDIT: Як я зазначив в одному з коментарів нижче, те, що я насправді хотів, було призупинити призупинення, коли мій ПК обслуговував файли через 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

EDIT 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

Замість того, щоб захаращувати питання, ви повинні поставити два варіанти вирішення проблеми як відповідь нижче.
Кас

Відповіді:


8

Програма, яка підтримує ваш комп'ютер без сну, - це кофеїн . Я б створив .bash_aliases файл, щоб також викликати кофеїн, коли викликається ваш вихідний код.

alias newname="origcode && caffeine"

Залежно від того, для якого коду ви намагаєтесь підтримувати ваш комп'ютер неспаним, вам доведеться скласти спеціальний скрипт, який включає введення кофеїну, коли інший код зупинений. Ще кілька деталей щодо конкретного коду допоможуть.

Оновлення: Більш простим способом було б запуск xdotool , який можна встановити sudo apt-get install xdotool. Ви можете написати сценарій, який викликається, коли ваш цільовий код відкрито, а потім використовувати sleepкоманду протягом 29 хвилин, а потім запустити xdotool key aабо щось довільне, щоб комп'ютер пробуджувався.


2
Для xdo, мабуть, краще вибрати ключ, який по суті не робить щось. Наприклад, натискання клавіші Shift, наприклад, призведе до екрана без набору активного вікна.
Олі

1
Дякую. Я навмисно приховував трохи деталей у первісному запитанні - те, що я прямо хочу зробити, це зупинити мій комп'ютер (який подає медіа-контент через NFS), призупинившись, поки мій медіа-центр отримує доступ до нього. Якщо ви знаєте спосіб спеціально вирішити цю проблему, це було б чудово, інакше я можу побачити пару способів, які дозволять це працювати через кофеїн (наприклад, медіа-центр схилятиметься до мого ПК кожні 10 хвилин і запускає сценарій оболонки, який спить протягом 15 хвилин).
Зорн

1
Я спробував кофеїн, і, здається, він працює, за винятком того, що коли програма, яка працює, зникає, виведення кофеїну говорить, що призупинення роботи більше не гальмується, але я залишив його вдвічі більше періоду бездіяльності, і хоча екран призупинено на ПК ніколи не робився. Я пограю з цим далі, хоча маршрут xdo, мабуть, буде ще зручнішим, і я спробую це спершу. PS Чи є спосіб вставити нову рядок у коментар ?!
Зорн

5

Якщо

  1. Сценарій в /usr/lib/pm-utils/sleep.d може перевірити, чи працює програма та повернути 1, щоб вказати, що призупинення потрібно запобігти.
  2. Проблема "система потім відмовляється від зупинки автоматично, замість спроби ще раз через 30 хвилин" вирішується переміщенням миші, яка знову запускає таймер (я сподіваюся, що я правильно зрозумів, що ви маєте на увазі під цим)

то чому б не просто перемістити покажчик миші після закінчення програми.

Підсумовувати:

  1. Використовуйте sleep.d, щоб запобігти призупиненню роботи системи.
  2. Напишіть сценарій, який клацне мишкою один раз.
  3. Зателефонуйте "Довготривалий сценарій && mousejiggle"

Це не завадить заставки.

Єдина проблема полягає в тому, що це буде через 30 хвилин після закінчення процесу, коли система призупиниться. Це стосується і вашого рішення "EDIT".

PS: Я шукав рішення подібної проблеми, коли дізнався про xdotool з цієї сторінки. Отже, дякую. Сподіваюсь, це допомагає.


Геніальний, дякую! Я дам це піти ці вихідні.
Зорн

Підказка про pm-utilsдопомогу. Зауважте, що пакет pm-utilsповинен бути встановлений для того, щоб це працювало - сам каталог може існувати, навіть якщо пакет не встановлений.
krlmlr

1

Незважаючи на те, що EDIT 2 дозволяє запустити заставку і поновлює послугу автоматичного розповсюдження після видалення файлу гальмування, як зазначено вище, після видалення файлу, коли система буде призупинена, це буде через 30 хвилин.

Одне можливе рішення - відключити вбудовану автоматичну заставку та функцію автоматичного призупинення та реалізувати їх самостійно та вибрати необхідну поведінку таймера. Команда xprintidle(можливо, доведеться встановити це) друкує кількість мілісекунд, протягом яких не було активності клавіатури чи миші. Це відкриває кілька можливостей. Я реалізував наступний диспетчер бездіяльності в python (не надто багато 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 &. що основні реалізації козирять спеціальні).
  2. Можливо, вам доведеться встановити xprintidle.

Як потрапляє файл заборони, зараз залишається уяві користувача (якщо я змушу себе реалізувати демон для цього, я поставлю це в EDIT до цієї відповіді). Ви, звичайно, вирішили це для своєї справи. Одним із недоліків, яких слід уникати при спробі призупинити призупинення більш ніж одного процесу, є видалення файлу блокування, коли один процес припиняється, а інший все ще працює. Крім того, сценарій можна трохи редагувати, щоб призупинити призупинення, якщо якийсь файл існує у певному каталозі (каталог замків). Таким чином, кожен процес може мати власний файл блокування.

Примітки:

  1. Цей сценарій досить легкий для процесора та пам'яті. Але видалення time.sleep (1) s з коду може спричинити проблеми - хоч не перевіряли.
  2. pm-suspend вимагає дозволу судо. До вечора-призупинення роботи без введення пароля Як запустити певні команди sudo без пароля? . Крім того, ви можете запустити цей скрипт у режимі sudo і зробити цей скрипт придатним без пароля (Не проблема, якщо сценарій використовується як root)
  3. Сценарій може зіткнутися з проблемою, якщо час очікування буде менше ~ 10 секунд (я не перевіряю, де саме починаються проблеми, має бути менше 5, я думаю). Це можна вирішити, видаливши деякий час.спля (1) s за рахунок системних ресурсів. Не думаю, що комусь це знадобиться.
  4. Оскільки у нас є рукоятка на таймерах, не потрібні мишобійні мигли!
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.