Bagaimana cara menghentikan sementara waktu?

10

Saya telah mencari sekitar sedikit untuk ini dan sepertinya tidak dapat menemukan sesuatu yang bermanfaat.

Saya memiliki PC saya yang menjalankan Ubuntu 12.10 diatur untuk ditunda setelah 30 menit tidak aktif. Saya tidak ingin mengubahnya, itu berfungsi sangat baik sebagian besar waktu.

Yang ingin saya lakukan adalah menonaktifkan penangguhan otomatis jika aplikasi tertentu sedang berjalan. Bagaimana saya bisa melakukan ini?

Hal terdekat yang saya temukan sejauh ini adalah menambahkan skrip shell /usr/lib/pm-utils/sleep.dyang memeriksa apakah aplikasi sedang berjalan dan mengembalikan 1 untuk menunjukkan bahwa penangguhan harus dicegah. Tetapi sepertinya sistem kemudian menyerah pada penangguhan secara otomatis, alih-alih mencoba lagi setelah 30 menit. (Sejauh yang saya tahu, jika saya menggerakkan mouse, itu me-restart timer lagi.) Sangat mungkin aplikasi akan selesai setelah beberapa jam, dan saya lebih suka PC saya kemudian ditangguhkan secara otomatis jika saya tidak menggunakan pada titik itu . (Jadi saya tidak ingin menambahkan panggilan ke pm-menangguhkan ketika aplikasi selesai.)

Apakah ini mungkin?

EDIT: Seperti yang saya catat di salah satu komentar di bawah, apa yang sebenarnya saya inginkan adalah untuk menghentikan sementara ketika PC saya melayani file melalui NFS; Saya hanya ingin fokus pada bagian "menangguhkan" dari pertanyaan karena saya sudah punya ide bagaimana menyelesaikan bagian NFS. Menggunakan ide 'xdotool' yang diberikan dalam salah satu jawaban, saya telah membuat skrip berikut yang saya jalankan dari cron setiap beberapa menit. Ini tidak ideal karena menghentikan screensaver juga, tetapi berhasil. Saya perlu melihat mengapa 'kafein' tidak mengaktifkan kembali dengan benar nanti, maka saya mungkin bisa melakukan yang lebih baik. Bagaimanapun, ini sepertinya berhasil, jadi saya memasukkannya di sini kalau-kalau ada orang lain yang tertarik.

#!/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: Skrip di atas berfungsi tetapi berkat komentar lain di bawah ini, saya sekarang menggunakan pasangan skrip ini, yang memiliki keuntungan memungkinkan screensaver untuk menendang sementara saya menghambat penangguhan. Yang pertama adalah /usr/lib/pm-utils/sleep.d/000nfs-inhibit, yang akan mencegah upaya penangguhan jika ada file penghambat:

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

Yang kedua adalah versi modifikasi dari skrip nfs-suspend-blocker sebelumnya dan masih harus dijalankan dari cron. Sekarang mengikuti strategi yang dijelaskan dalam komentar di bawah:

#!/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
Zorn
sumber
Alih-alih mengacaukan pertanyaan Anda harus meletakkan dua solusi Anda untuk masalah sebagai jawaban di bawah ini.
Cas

Jawaban:

8

Program untuk membuat komputer Anda tetap terjaga adalah Kafein . Saya akan membuat file .bash_aliases untuk juga memanggil kafein ketika kode asli Anda dipanggil.

alias newname="origcode && caffeine"

Bergantung pada kode yang Anda coba jaga agar komputer Anda tetap terjaga, Anda harus membuat skrip khusus yang termasuk mematikan kafein ketika kode lain dihentikan. Beberapa detail lebih lanjut tentang kode tertentu akan membantu.

Pembaruan: Cara yang lebih sederhana adalah dengan menjalankan xdotool , yang dapat diinstal dengan sudo apt-get install xdotool. Anda dapat menulis skrip yang dipanggil saat kode target dibuka dan kemudian menggunakan sleepperintah selama 29 menit dan kemudian menjalankan xdotool key aatau sesuatu yang sewenang-wenang agar komputer tetap terjaga.

philshem
sumber
2
Untuk xdo, mungkin lebih baik untuk memilih kunci yang secara inheren tidak melakukan sesuatu. Menekan shift, misalnya, akan membangunkan layar tanpa mengetik di jendela aktif.
Oli
1
Terima kasih. Saya sengaja menyembunyikan sedikit detail dalam pertanyaan awal - apa yang ingin saya lakukan secara eksplisit adalah menghentikan PC saya (yang menyajikan konten media melalui NFS) yang ditangguhkan sementara pusat media saya mengaksesnya. Jika Anda tahu cara untuk secara khusus mengatasi hal ini yang akan menjadi hebat, jika tidak, saya bisa melihat beberapa jalan yang akan memungkinkan ini bekerja melalui Kafein (misalnya pusat media akan ssh ke PC saya setiap 10 menit dan menjalankan skrip shell yang tertidur untuk 15 menit).
Zorn
1
Saya telah mencoba Caffeine dan tampaknya bekerja kecuali bahwa begitu program berjalan menghilang, output Caffeine mengatakan penundaan tidak lagi terhambat tetapi saya meninggalkannya dua kali periode tidak aktif dan meskipun layar ditangguhkan PC tidak pernah melakukannya. Saya akan bermain-main dengan ini lebih lanjut, meskipun rute xdo mungkin akan lebih nyaman dan saya akan mencobanya terlebih dahulu. PS Apakah ada cara untuk memasukkan baris baru ke dalam komentar ?!
Zorn
5

Jika

  1. Sebuah skrip di /usr/lib/pm-utils/sleep.d dapat memeriksa apakah aplikasi sedang berjalan dan mengembalikan 1 untuk menunjukkan bahwa penangguhan harus dicegah.
  2. Masalah "sistem kemudian menyerah pada penangguhan secara otomatis, alih-alih mencoba lagi setelah 30 menit" diselesaikan dengan menggerakkan mouse yang me-restart timer lagi (saya harap saya mengerti benar apa yang Anda maksud dengan ini)

lalu mengapa tidak hanya goncang penunjuk mouse setelah aplikasi berakhir.

Untuk meringkas:

  1. Gunakan sleep.d untuk menjaga sistem dari menangguhkan.
  2. Tulis skrip yang menggoncang mouse sekali.
  3. Sebut 'Skrip berjalan lama && mousejiggle'

Ini tidak akan menghalangi screensaver.

Satu-satunya masalah adalah bahwa itu akan menjadi 30 menit setelah proses berakhir ketika sistem ditangguhkan. Ini adalah masalah dengan solusi 'EDIT' Anda juga.

PS: Saya sedang mencari solusi untuk masalah yang sama ketika saya belajar xdotool dari halaman ini. Jadi terima kasih. Semoga ini membantu.

S Prasanth
sumber
Cerdik, terima kasih! Saya akan mencobanya akhir pekan ini.
Zorn
Petunjuk tentang pm-utilsmembantu. Perhatikan bahwa paket pm-utilsperlu diinstal agar ini berfungsi - direktori itu sendiri mungkin ada bahkan jika paket tidak diinstal.
krlmlr
1

Meskipun EDIT 2 memungkinkan screensaver kick-in dan melanjutkan layanan autosuspend untuk menghapus file yang dihambat, seperti yang disebutkan di atas, 30 menit setelah file dihapus ketika sistem akan ditangguhkan.

Salah satu solusi yang mungkin adalah dengan menonaktifkan bawaan-screensaver dan fungsi auto-suspend inbuilt dan menerapkannya pada kita sendiri, dan memilih perilaku timer yang diperlukan. Perintah xprintidle(Anda mungkin harus menginstal ini) mencetak jumlah milidetik yang belum ada aktivitas keyboard atau mouse. Ini membuka beberapa kemungkinan. Saya telah menerapkan manajer tidak aktif berikut dalam python (tidak terlalu banyak bash scripter). Fitur termasuk mengatur perintah, batas waktu dan menghambat file (saya menyebutnya kunci) untuk screensaver dan / atau belanja otomatis. Selain itu ada opsi untuk memilih apakah timer tidak aktif harus memulai kembali ketika file terhapus dihapus atau tidak (perilaku dapat berbeda untuk menangguhkan dan screensaver). Saya sudah mencoba menjelaskan penggunaannya di catatan tetapi jika ada sesuatu yang tidak jelas, tanyakan.

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

Pemakaian:

  1. Cukup tambahkan inactivitymanager &ke .profile atau .xsessionrc di direktori home (lihat mana yang cocok untuk Anda. Jangan tambahkan keduanya, kalau tidak dua contoh skrip ini akan berjalan secara bersamaan, sesuatu yang belum saya tangani. Saya kira ini ada dalam perincian ini bahwa implementasi utama mengalahkan yang khusus).
  2. Anda mungkin harus menginstal xprintidle.

Bagaimana file penghambat sampai di sana diserahkan kepada imajinasi pengguna untuk saat ini (jika saya membawa diri saya untuk mengimplementasikan daemon untuk ini, saya akan memasukkannya ke dalam EDIT untuk jawaban ini). Anda (OP) tentu saja telah menyelesaikannya untuk kasus Anda. Satu perangkap yang harus dihindari ketika mencoba untuk menghentikan penangguhan selama lebih dari satu proses adalah menghapus file kunci ketika satu proses berakhir sementara yang lain masih berjalan. Atau, skrip dapat diedit sedikit untuk menghambat penangguhan jika beberapa file ada di direktori tertentu (direktori kunci). Dengan cara ini setiap proses dapat memiliki file kunci sendiri.

Catatan:

  1. Script ini cukup ringan pada prosesor dan memori. Tetapi menghapus time.sleep (1) dalam kode dapat menyebabkan masalah - belum diperiksa.
  2. pm-suspend membutuhkan izin sudo. Untuk pm-menangguhkan tanpa memberikan checkout kata sandi Bagaimana cara menjalankan perintah sudo tertentu tanpa kata sandi? . Atau Anda dapat menjalankan skrip ini dalam mode sudo, dan menjadikan skrip ini sudoable tanpa kata sandi (Tidak masalah jika Anda menjalankan skrip sebagai root)
  3. Skrip mungkin mengalami masalah jika batas waktu ditetapkan kurang dari ~ 10 detik (Belum memeriksa di mana tepatnya masalah dimulai harus kurang dari 5, kurasa). Ini dapat ditangani dengan menghapus beberapa waktu. Tidur (1) dengan mengorbankan sumber daya sistem. Jangan berpikir siapa pun akan membutuhkan ini.
  4. Karena kami memiliki pegangan pada penghitung waktu, tidak ada tetikus yang diperlukan!
S Prasanth
sumber