web-dev-qa-db-ja.com

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

私はこれを少し探してみましたが、役に立つものは見つかりませんでした。

Ubuntuを実行している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
9
Zorn

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

alias newname="origcode && caffeine"

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

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

7
philshem

もし

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

次に、アプリケーションの終了後にマウスポインターを揺らすだけではどうでしょうか。

要約すると:

  1. Sleep.dを使用して、システムが中断しないようにします。
  2. マウスを1回揺らすスクリプトを作成します。
  3. 「長時間実行スクリプト&& mousejiggle」を呼び出す

これはスクリーンセーバーを妨げません。

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

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

5
S Prasanth

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. https://askubuntu.com/questions/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. ホームディレクトリの.profileまたは.xsessionrcにinactivitymanager &を追加するだけです(どちらが適切かを確認してください。両方を追加しないでください。追加しないと、このスクリプトの2つのインスタンスが同時に実行されます。これらの詳細において、主流の実装がカスタム実装より優先されます)。
  2. Xprintidleをインストールする必要がある場合があります。

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

ノート:

  1. このスクリプトは、プロセッサとメモリをかなり軽くしています。ただし、コード内のtime.sleep(1)を削除すると、問題が発生する可能性があります-ただし、チェックはしていません。
  2. pm-suspendにはSudo権限が必要です。パスワードをチェックアウトせずにpm-suspendする パスワードなしで特定のSudoコマンドを実行するにはどうすればよいですか? 。または、このスクリプトをSudoモードで実行し、パスワードなしでこのスクリプトをsudoableにすることもできます(スクリプトをrootとして実行している場合は問題ありません)
  3. タイムアウトを10秒未満に設定すると、スクリプトで問題が発生する可能性があります(トラブルが発生する場所を正確に確認しないでください)。これは、システムリソースを犠牲にしてtime.sleep(1)を削除することで処理できます。ただし、これが必要になるとは思わないでください。
  4. タイマーにハンドルがあるため、マウスを動かす必要はありません!
1
S Prasanth