如何抑制暂时暂停?


10

我已经搜索了一下,似乎找不到任何帮助。

我将运行Ubuntu 12.10的PC设置为在30分钟不活动后挂起。我不想更改它,它在大多数情况下都有效。

我要做的是如果正在运行特定的应用程序,则禁用自动挂起。我怎样才能做到这一点?

到目前为止,我找到的最接近的内容是添加一个shell脚本,在/usr/lib/pm-utils/sleep.d其中检查应用程序是否正在运行,并返回1表示应防止挂起。但是看起来系统然后放弃了自动挂起,而不是再等待30分钟再尝试一次。(据我所知,如果我移动鼠标,那将再次重新启动计时器。)很有可能,应用程序将在几个小时后完成,我宁愿我的PC 在不使用时自动挂起。在那个时候。(因此,我不想在应用程序完成时向pm-suspend添加调用。)

这可能吗?

编辑:正如我在下面的评论之一中指出的那样,我真正想要的是在PC通过NFS提供文件时禁止挂起;我只想关注问题的“挂起”部分,因为我已经有了解决NFS部分的想法。使用答案之一给出的“ xdotool”想法,我想出了以下每隔几分钟从cron运行一次的脚本。这是不理想的,因为它也会阻止屏幕保护程序启动,但确实可以。我需要看看为什么'caffeine'之后无法正确重新启用暂停功能,所以我可能会做得更好。无论如何,这似乎确实可行,因此,如果有人对它感兴趣,我将其包括在这里。

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

Answers:


8

Caffeine是使计算机保持苏醒的程序。当您调用原始代码时,我会制作一个.bash_aliases文件来同时调用咖啡因。

alias newname="origcode && caffeine"

根据您要使计算机保持清醒状态的代码,您必须创建一个自定义脚本,其中包括在其他代码停止时杀死咖啡因。有关特定代码的更多详细信息将有所帮助。

更新:一种更简单的方法是运行xdotool,可以使用进行安装sudo apt-get install xdotool。您可以编写一个在打开目标代码时调用的脚本,然后使用该sleep命令29分钟,然后运行xdotool key a或执行任意操作以保持计算机苏醒。


2
对于xdo,最好选择一个本质上不做任何事情的键。例如,按shift键将唤醒屏幕,而无需在活动窗口中键入。
奥利(Oli)

1
谢谢。我故意在原始问题中隐藏了一些细节-我明确想做的是在媒体中心访问PC时停止其PC(通过NFS提供媒体内容)的挂起。如果您知道一种专门解决此问题的方法,那将是很好的选择,否则,我会看到几种途径,这些途径可以通过Caffeine来实现(例如,媒体中心每10分钟就会进入我的PC并运行一个休眠的Shell脚本) 15分钟)。
Zorn 2012年

1
我尝试过使用Caffeine,它似乎可以正常工作,只是一旦运行的程序消失了,Caffeine的输出就说暂停不再被禁止,但是我将其保留了两倍的不活动时间,尽管屏幕暂停PC从来没有。尽管xdo路由可能会更加方便,但我将首先尝试一下。PS有没有办法在评论中插入换行符?
Zorn 2012年

5

如果

  1. /usr/lib/pm-utils/sleep.d中的脚本可以检查应用程序是否正在运行,并返回1表示应防止挂起。
  2. 通过移动鼠标来重新启动计时器,可以解决“系统然后放弃自动挂起,而不是再等待30分钟再尝试”的问题(希望我已经正确理解了这是什么意思)

那么为什么不只是在应用程序终止后轻摇鼠标指针。

总结一下:

  1. 使用sleep.d可以防止系统挂起。
  2. 编写一个使鼠标摇动一次的脚本。
  3. 调用“长时间运行的脚本&& mousejiggle”

这不会妨碍屏幕保护程序。

唯一的问题是,在系统挂起时,该过程将在30分钟后终止。您的“编辑”解决方案也是如此。

PS:从此页面了解xdotool时,我正在寻找解决类似问题的方法。那谢谢啦。希望这可以帮助。


精巧,谢谢!这个周末我会去的。
Zorn 2012年

有关的提示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 &到主目录中的.profile或.xsessionrc中(请参阅哪一个对您有用。不要同时添加两者,否则此脚本的两个实例将同时运行,而我尚未处理。我想这是这些详细信息主流实现胜过自定义)。
  2. 您可能必须安装xprintidle。

禁止文件如何到达那里,现在还留给用户想象(如果我自己为此实现一个守护程序,则将其放在此答案的EDIT中)。您(OP)当然已经为您解决了这个问题。试图禁止一个以上进程暂停时要避免的一个陷阱是,当一个进程终止而另一个进程仍在运行时,删除锁定文件。另外,如果特定目录(锁定目录)中存在某些文件,则可以对脚本进行少量编辑以禁止挂起。这样,每个进程都可以拥有自己的锁定文件。

笔记:

  1. 该脚本对处理器和内存的影响很小。但是删除代码中的time.sleep(1)可能会引起麻烦-尚未检查。
  2. pm-suspend需要sudo权限。在不提供密码签出的情况下挂起pm-suspend 如何在没有密码的情况下运行特定的sudo命令?。或者,您可以在sudo模式下运行此脚本,并使该脚本可在没有密码的情况下变为sudoable(如果您以root用户身份运行脚本,则没有问题)
  3. 如果将超时设置为小于约10秒,则脚本可能会遇到麻烦(我想不能检查问题的确切开始地点必须小于5秒)。这可以通过删除一些time.sleep(1)来解决,而这会浪费系统资源。不要以为有人会需要这个。
  4. 因为我们在计时器上有一个手柄,所以不需要鼠标摇晃!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.