一時停止を一時的に禁止する方法は?


10

私はこれについて少し検索しましたが、役立つものを見つけることができないようです。

Ubuntu 12.10を実行しているPCで、30分間何も操作しないと一時停止するように設定しています。私はそれを変えたくありません、それはほとんどの場合うまくいきます。

特定のアプリケーションが実行されている場合、自動サスペンドを無効にしたいのですが。これどうやってするの?

これまでに見つけた最も近いものは/usr/lib/pm-utils/sleep.d、アプリケーションが実行されているかどうかをチェックし、1を返して中断を防止する必要があることを示すシェルスクリプトを追加することです。しかし、システムは、その後30分後に再試行するのではなく、自動的に中断することをあきらめるように見えます。(私が知る限り、マウスを動かすと、タイマーが再起動します。)アプリケーションは数時間後に終了する可能性が高く、使用していない場合はPCを自動的に一時停止したほうがよいでしょう。その時点でそれ。(したがって、アプリケーションの終了時にpm-suspendへの呼び出しを追加したくありません。)

これは可能ですか?

編集:以下のコメントの1つで述べたように、実際に必要だったのは、PCがNFS経由でファイルを提供しているときにサスペンドを禁止することでした。NFSの部分を解決する方法をすでに考えていたので、質問の「サスペンド」の部分に焦点を当てたかっただけです。回答の1つにある「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:上記のスクリプトは機能しますが、以下の別のコメントのおかげで、私はこのスクリプトのペアを使用しています。これは、サスペンドを禁止している間、スクリーンセーバーが起動できるという利点があります。1つ目は/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

2つ目は、以前の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

質問を散らかすのではなく、問題に対する2つの解決策を以下の回答として提示する必要があります。
Cas

回答:


8

コンピュータを起動させ続けるプログラムはCaffeineです。.bash_aliasesファイルを作成して、元のコードが呼び出されたときにカフェインも呼び出すようにします。

alias newname="origcode && caffeine"

コンピューターをスリープ状態にしないようにするコードに応じて、他のコードが停止したときにカフェインを強制終了することを含むカスタムスクリプトを作成する必要があります。特定のコードに関する詳細がさらに役立つでしょう。

更新:より簡単な方法は、でインストールできるxdotoolを実行することsudo apt-get install xdotoolです。ターゲットコードが開いたときに呼び出されるスクリプトを記述し、sleepコマンドを29分間使用してxdotool key aから、任意の何かを実行して、コンピューターをスリープ状態に保つことができます。


2
xdoの場合、本質的には何もしないキーを選択する方が良いでしょう。たとえば、Shiftキーを押すと、アクティブなウィンドウに入力しなくても画面が復帰します。
オリ

1
ありがとうございました。私は元の質問に意図的に少し詳細を隠していました-私が明確にしたいのは、メディアセンターがアクセスしている間、(NFSを介してメディアコンテンツを提供している)PCを一時停止することです。これに具体的に対処する方法がわかっている場合はすばらしいですが、そうでない場合は、カフェインを介してこれを機能させるいくつかの方法を確認できます(たとえば、メディアセンターがPCに10分ごとにsshして、スリープするシェルスクリプトを実行します15分間)。
Zorn、

1
私はカフェインを試してみましたが、実行中のプログラムが消えると、カフェイン出力はサスペンドがもはや禁止されていないことを示していますが、非アクティブ期間の2倍の間それを残しましたが、画面がPCをサスペンドしたことはありませんでした。xdoルートはおそらくもっと便利になるでしょうが、私はそれを最初に試すつもりですが、私はこれでさらに遊んでいきます。PSコメントに改行を挿入する方法はありますか?!
Zorn

5

もし

  1. /usr/lib/pm-utils/sleep.d内のスクリプトは、アプリケーションが実行されているかどうかを確認し、サスペンドを防止する必要があることを示す1を返すことができます。
  2. 「システムはさらに30分後に再試行するのではなく、自動的に中断することをあきらめます」という問題は、タイマーを再起動するマウスを動かすことによって解決されます(これが何を意味するのかを正しく理解できたと思います)

次に、アプリケーションが終了した後、マウスポインタを揺らすだけではないのです。

要約すると:

  1. システムがサスペンドしないようにするには、sleep.dを使用します。
  2. マウスを1回揺らすスクリプトを作成します。
  3. 「長時間実行スクリプト&&マウスジグル」を呼び出す

これはスクリーンセーバーの妨げにはなりません。

唯一の問題は、システムが一時停止したときにプロセスが終了してから30分になることです。これは、「編集」ソリューションにも当てはまります。

PS:このページからxdotoolについて知ったとき、私は同様の問題の解決策を探していました。ほんとありがと。お役に立てれば。


独創的、ありがとう!今週末に行ってみます。
Zorn、

pm-utils助けに関するヒント。pm-utilsこれが機能するには、パッケージをインストールする必要があることに注意してください。パッケージがインストールされていなくても、ディレクトリ自体が存在する場合があります。
krlmlr 2015年

1

EDIT 2では、禁止ファイルを削除するとスクリーンセーバーが起動し、自動サスペンドサービスが再開されますが、上記のように、ファイルが削除されてから30分後にシステムがサスペンドします。

可能な解決策の1つは、組み込みの自動スクリーンセーバーと自動一時停止機能を無効にして、独自に実装し、必要に応じてタイマーの動作を選択することです。コマンド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つのインスタンスが同時に実行され、処理されませんでした。これらの詳細にあると思います主流の実装はカスタムのものよりも優先されます)。
  2. xprintidleをインストールする必要がある場合があります。

禁止ファイルがどのように取得されるかは、今のところユーザーの想像力に任されています(このためのデーモンを実装するように自分を導いた場合、それをこの回答の編集に入れます)。もちろんあなた(OP)はあなたのケースのためにそれを解決しました。複数のプロセスのサスペンドを禁止しようとするときに避けるべき落とし穴の1つは、あるプロセスがまだ実行中であるときに1つのプロセスが終了すると、ロックファイルを削除することです。または、スクリプトを少し編集して、特定のディレクトリ(ロックディレクトリ)にファイルが存在する場合にサスペンドを禁止することもできます。このように、各プロセスは独自のロックファイルを持つことができます。

ノート:

  1. このスクリプトは、プロセッサとメモリに関しては非常に軽量です。しかし、コードからtime.sleep(1)を削除すると問題が発生する可能性があります-チェックしていません。
  2. pm-suspendにはsudo権限が必要です。パスワードのチェックアウトを行わずにpm-suspend を実行するには特定のsudoコマンドをパスワードなしで実行するにはどうすればよいですか?。または、このスクリプトをsudoモードで実行し、このスクリプトをパスワードなしでsudo可能にすることもできます(rootとしてスクリプトを実行している場合は問題ありません)。
  3. タイムアウトが10秒未満に設定されている場合、スクリプトが問題を起こす可能性があります(問題の発生箇所が5未満でなければならないことを確認しないでください)。これは、システムリソースを犠牲にしてtime.sleep(1)を削除することで処理できます。だれでもこれが必要になるとは思わないでください。
  4. タイマーにハンドルがあるため、マウスジグルは必要ありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.