จะระงับชั่วคราวได้อย่างไร?


10

ฉันค้นหาสิ่งนี้แล้วดูเหมือนจะไม่สามารถหาอะไรที่เป็นประโยชน์ได้

ฉันมีคอมพิวเตอร์ที่ใช้ Ubuntu 12.10 ตั้งค่าให้ระงับหลังจากไม่มีกิจกรรมเป็นเวลา 30 นาที ฉันไม่ต้องการเปลี่ยนมันใช้งานได้ดีตลอดเวลา

สิ่งที่ฉันต้องการทำคือปิดการใช้งานการระงับอัตโนมัติหากแอปพลิเคชันบางตัวกำลังทำงานอยู่ ฉันจะทำสิ่งนี้ได้อย่างไร

สิ่งที่ใกล้เคียงที่สุดที่ฉันเคยพบคือการเพิ่มเชลล์สคริปต์/usr/lib/pm-utils/sleep.dที่ตรวจสอบว่าแอปพลิเคชันทำงานอยู่และส่งคืน 1 เพื่อระบุว่าควรจะป้องกันการหยุดทำงานชั่วคราวหรือไม่ แต่ดูเหมือนว่าระบบจะยกเลิกการระงับโดยอัตโนมัติแทนที่จะลองอีกครั้งในอีก 30 นาที (เท่าที่ผมสามารถบอกได้ว่าถ้าผมเลื่อนเมาส์ไปที่เตะจับเวลาอีกครั้ง.) มันค่อนข้างจะมีโปรแกรมจะเสร็จสมบูรณ์หลังจากที่ไม่กี่ชั่วโมงและฉันอยากจะพีซีของฉันแล้วระงับโดยอัตโนมัติถ้าฉันไม่ได้ใช้ มันอยู่ที่จุดนั้น (ดังนั้นฉันไม่ต้องการเพิ่มการโทรไปที่ pm-suspend เมื่อแอปพลิเคชันเสร็จสิ้น)

เป็นไปได้ไหม

แก้ไข: ตามที่ฉันได้กล่าวไว้ในความคิดเห็นด้านล่างสิ่งที่ฉันต้องการคือการยับยั้งการหยุดชั่วคราวเมื่อพีซีของฉันแสดงไฟล์ผ่าน 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

โปรแกรมเพื่อให้ตื่นตัวคอมพิวเตอร์ของคุณเป็นคาเฟอีน ฉันจะสร้างไฟล์. bash_aliases เพื่อเรียกคาเฟอีนด้วยเมื่อรหัสเดิมของคุณถูกเรียก

alias newname="origcode && caffeine"

ขึ้นอยู่กับรหัสที่คุณพยายามทำให้คอมพิวเตอร์ตื่นตัวคุณจะต้องสร้างสคริปต์ที่กำหนดเองซึ่งรวมถึงการฆ่าคาเฟอีนเมื่อรหัสอื่นหยุดทำงาน รายละเอียดเพิ่มเติมเกี่ยวกับรหัสบางอย่างจะช่วยได้

อัปเดต:วิธีที่ง่ายกว่าคือการเรียกใช้xdotoolซึ่งสามารถติดตั้งsudo apt-get install xdotoolได้ คุณสามารถเขียนสคริปต์ที่ถูกเรียกเมื่อรหัสเป้าหมายของคุณถูกเปิดและจากนั้นใช้sleepคำสั่งเป็นเวลา 29 นาทีจากนั้นเรียกใช้xdotool key aหรือบางสิ่งบางอย่างตามอำเภอใจเพื่อให้คอมพิวเตอร์ตื่นตัว


2
สำหรับ xdo น่าจะดีกว่าถ้าเลือกคีย์ที่ไม่ได้ทำอะไรเลย ตัวอย่างเช่นการกด shift จะปลุกหน้าจอโดยไม่พิมพ์บนหน้าต่างที่ใช้งานอยู่
Oli

1
ขอบคุณ. ฉันตั้งใจซ่อนรายละเอียดเล็กน้อยในคำถามต้นฉบับ - สิ่งที่ฉันต้องการทำอย่างชัดเจนคือหยุดพีซีของฉัน (ซึ่งให้บริการเนื้อหาสื่อผ่าน NFS) ที่ถูกระงับขณะที่ศูนย์สื่อของฉันกำลังเข้าถึง ถ้าคุณรู้วิธีที่จะกล่าวถึงเรื่องนี้โดยเฉพาะจะดีมากมิฉะนั้นฉันจะเห็นลู่ทางสองสามสายซึ่งจะอนุญาตให้ทำงานผ่าน Caffeine (เช่น media center จะ ssh ลงในพีซีของฉันทุก 10 นาทีและรันเชลล์สคริปต์ที่หลับ 15 นาที)
Zorn

1
ฉันลอง Caffeine และดูเหมือนว่าจะทำงานยกเว้นว่าเมื่อโปรแกรมที่ทำงานหายไป Caffeine output บอกว่าการหยุดชั่วคราวไม่มีการยับยั้งอีกต่อไป แต่ฉันทิ้งไว้สองครั้งในช่วงที่ไม่มีการใช้งานและถึงแม้ว่าหน้าจอจะไม่หยุดทำงานพีซี ฉันจะเล่นรอบนี้ต่อไปแม้ว่าเส้นทาง xdo น่าจะสะดวกกว่าและฉันจะลองก่อน ป.ล. มีวิธีการแทรกบรรทัดใหม่ในความคิดเห็นหรือไม่!
Zorn

5

ถ้า

  1. สคริปต์ใน /usr/lib/pm-utils/sleep.d สามารถตรวจสอบว่าแอปพลิเคชันทำงานอยู่หรือไม่และส่งคืน 1 เพื่อระบุว่าควรจะป้องกันการหยุดทำงานชั่วคราวหรือไม่
  2. ปัญหาของ "ระบบยอมแพ้โดยอัตโนมัติแทนที่จะลองอีกครั้งหลังจากผ่านไป 30 นาที" แก้ไขได้โดยเลื่อนเมาส์ที่รีสตาร์ทตัวจับเวลาอีกครั้ง (ฉันหวังว่าฉันเข้าใจอย่างถูกต้องว่าคุณหมายถึงอะไร)

แล้วทำไมไม่เพียงแค่ขยับตัวชี้เมาส์หลังจากแอปพลิเคชั่นหยุดทำงาน

เพื่อสรุป:

  1. ใช้ sleep.d เพื่อป้องกันระบบจากการระงับ
  2. เขียนสคริปต์ที่กระตุกเมาส์หนึ่งครั้ง
  3. โทรหา 'สคริปต์ระยะยาว && mousejiggle'

นี่จะไม่เป็นอุปสรรคต่อสกรีนเซฟเวอร์

ปัญหาเดียวคือว่าจะใช้เวลา 30 นาทีหลังจากกระบวนการยุติลงเมื่อระบบหยุดทำงาน นี่เป็นกรณีของโซลูชัน 'แก้ไข' ของคุณด้วย

PS: ฉันกำลังมองหาวิธีการแก้ไขปัญหาที่คล้ายกันเมื่อฉันเรียนรู้ของ xdotool จากหน้านี้ ดังนั้นขอบคุณ หวังว่านี่จะช่วยได้


แยบยลขอบคุณ! ฉันจะให้มันไปสุดสัปดาห์นี้
Zorn

คำแนะนำเกี่ยวกับการpm-utilsช่วยเหลือ โปรดทราบว่าpm-utilsจะต้องติดตั้งแพคเกจเพื่อให้สามารถใช้งานได้ - อาจมีไดเรกทอรีเองแม้ว่าจะไม่ได้ติดตั้งแพ็คเกจก็ตาม
krlmlr

1

แม้ว่า EDIT 2 จะอนุญาตให้สกรีนเซฟเวอร์เริ่มทำงานและให้บริการ autosuspend ต่อเมื่อทำการลบไฟล์ยับยั้งดังที่กล่าวไว้ข้างต้นจะใช้เวลา 30 นาทีหลังจากที่ไฟล์ถูกลบเมื่อระบบจะหยุดทำงาน

ทางออกหนึ่งที่เป็นไปได้คือการปิดการใช้งานสกรีนเซฟเวอร์อัตโนมัติ inbuilt และฟังก์ชั่นระงับการใช้งานอัตโนมัติและนำไปใช้งานด้วยตัวเราเอง คำสั่งxprintidle(คุณอาจต้องติดตั้งสิ่งนี้) พิมพ์จำนวนมิลลิวินาทีที่ไม่มีกิจกรรมแป้นพิมพ์หรือเมาส์ สิ่งนี้เปิดขึ้นเป็นไปได้หลายอย่าง ฉันใช้เครื่องมือจัดการความไม่มีกิจกรรมต่อไปนี้ในไพ ธ อน (ไม่ได้เป็นสแครปเตอร์ทุบตีมากเกินไป) คุณสมบัติรวมถึงการตั้งค่าคำสั่งหมดเวลาและยับยั้งไฟล์ (ฉันเรียกมันว่าล็อค) สำหรับสกรีนเซฟเวอร์และ / หรือ autosuspend นอกจากนี้ยังมีตัวเลือกให้เลือกว่าตัวจับเวลาไม่ทำงานเมื่อใดควรรีสตาร์ทเมื่อไฟล์การยับยั้งถูกลบหรือไม่ (พฤติกรรมสามารถแตกต่างกันสำหรับการหยุดชั่วคราวและสกรีนเซฟเวอร์) ฉันพยายามทำให้การใช้งานชัดเจนในบันทึกย่อ แต่หากมีสิ่งใดไม่ชัดเจนให้ถาม

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

วิธียับยั้งไฟล์จะมีจินตนาการของผู้ใช้เหลืออยู่ตอนนี้ (ถ้าฉันนำตัวเองไปใช้ daemon สำหรับสิ่งนี้ฉันจะนำสิ่งนั้นไปแก้ไขในคำตอบนี้) แน่นอนคุณ (OP) ได้แก้ไขมันสำหรับกรณีของคุณแล้ว ข้อผิดพลาดประการหนึ่งที่ควรหลีกเลี่ยงเมื่อพยายามยับยั้งการระงับมากกว่าหนึ่งกระบวนการคือการลบไฟล์ล็อคเมื่อกระบวนการหนึ่งยุติลงในขณะที่อีกกระบวนการหนึ่งกำลังทำงานอยู่ อีกทางหนึ่งสคริปต์สามารถแก้ไขได้เล็กน้อยเพื่อยับยั้งการระงับหากมีไฟล์บางไฟล์ในไดเรกทอรีเฉพาะ (ไดเรกทอรีล็อค) วิธีนี้แต่ละกระบวนการสามารถมีไฟล์ล็อคของตัวเอง

หมายเหตุ:

  1. สคริปต์นี้ค่อนข้างสว่างบนโปรเซสเซอร์และหน่วยความจำ แต่การลบ time.sleep (1) s ในโค้ดอาจทำให้เกิดปัญหา - ยังไม่ได้ตรวจสอบ
  2. pm-suspend ต้องการสิทธิ์ sudo ในการระงับการใช้งานโดยไม่ต้องชำระเงินรหัสผ่านฉันจะรันคำสั่ง sudo เฉพาะโดยไม่ต้องใช้รหัสผ่านได้อย่างไร . หรือคุณอาจเรียกใช้สคริปต์นี้ในโหมด sudo และทำให้สคริปต์นี้ sudoable โดยไม่ใช้รหัสผ่าน (ไม่ใช่ปัญหาหากคุณเรียกใช้สคริปต์ในฐานะ root)
  3. สคริปต์อาจมีปัญหาหากการหมดเวลาถูกตั้งค่าให้น้อยกว่า ~ 10 วินาที (ยังไม่ได้ตรวจสอบว่าปัญหาเริ่มต้นที่ใดจะต้องน้อยกว่า 5 ฉันเดา) สิ่งนี้สามารถจัดการได้โดยการลบ time.sleep (1) s บางส่วนออกจากค่าใช้จ่ายของทรัพยากรระบบ อย่าคิดว่าจะมีใครต้องการสิ่งนี้
  4. เนื่องจากเรามีมือจับบนตัวจับเวลาจึงไม่จำเป็นต้องใช้เมาส์!
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.