J'ai cherché un peu autour de ça et je n'arrive pas à trouver quelque chose d'utile.
Mon ordinateur exécutant Ubuntu 12.10 est configuré pour suspendre ses activités après 30 minutes d'inactivité. Je ne veux pas changer cela, cela fonctionne très bien la plupart du temps.
Ce que je veux faire, c'est désactiver la suspension automatique si une application particulière est en cours d'exécution. Comment puis-je faire ceci?
La chose la plus proche que j'ai trouvée jusqu'ici consiste à ajouter un script Shell dans /usr/lib/pm-utils/sleep.d
, qui vérifie si l'application est en cours d'exécution et renvoie 1 pour indiquer qu'il faut empêcher la suspension. Mais , il semble que le système abandonne alors automatiquement la suspension, au lieu de réessayer après 30 minutes supplémentaires. (Autant que je sache, si je déplace la souris, le chronomètre redémarre à nouveau.) Il est fort probable que l'application se terminera au bout de quelques heures et je préférerais que mon PC soit alors automatiquement suspendu si je ne l'utilise pas à ce moment-là . (Je ne souhaite donc pas ajouter d'appel à pm-suspend à la fin de l'application.)
Est-ce possible?
EDIT: Comme je l’ai noté dans l’un des commentaires ci-dessous, ce que je voulais réellement, c’était empêcher la suspension lorsque mon PC servait des fichiers sur NFS; Je voulais juste me concentrer sur la partie "suspension" de la question car j'avais déjà une idée de la façon de résoudre la partie NFS. En utilisant l’idée 'xdotool' donnée dans l’une des réponses, j’ai développé le script suivant, que je lance depuis cron toutes les quelques minutes. Ce n’est pas idéal car cela empêche l’écran de veille de démarrer, mais cela fonctionne. Je dois examiner pourquoi la "caféine" ne réactive pas correctement la suspension plus tard, alors je pourrais probablement faire mieux. Quoi qu'il en soit, cela semble fonctionner, alors je l'inclue ici au cas où quelqu'un d'autre serait intéressé.
#!/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: Le script ci-dessus fonctionne, mais grâce à un autre commentaire ci-dessous, j’utilise maintenant cette paire de scripts, qui ont l’avantage de permettre à l’économiseur d’écran d’intervenir pendant l’activation de la suspension. Le premier est /usr/lib/pm-utils/sleep.d/000nfs-inhibit, ce qui empêchera une tentative de suspension si un fichier d'inhibition existe:
#!/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
La seconde est une version modifiée du script précédent nfs-suspend-blocker et doit toujours être exécutée à partir de cron. Il suit maintenant la stratégie décrite dans le commentaire ci-dessous:
#!/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
Un programme pour garder votre ordinateur éveillé est Caféine . Je ferais un fichier .bash_aliases pour appeler également la caféine lorsque votre code d'origine est appelé.
alias newname="origcode && caffeine"
Selon le code pour lequel vous essayez de maintenir votre ordinateur en état de veille, vous devrez créer un script personnalisé incluant la suppression de la caféine lorsque l'autre code est arrêté. Quelques détails supplémentaires sur le code particulier pourraient aider.
Mise à jour: Un moyen plus simple serait de lancer xdotool , qui peut être installé avec Sudo apt-get install xdotool
. Vous pouvez écrire un script appelé à l'ouverture de votre code cible, puis utiliser la commande sleep
pendant 29 minutes, puis exécuter xdotool key a
ou utiliser un moyen quelconque pour maintenir l'ordinateur en état de veille.
Si
alors pourquoi ne pas simplement déplacer le pointeur de la souris après la fin de l’application.
Pour résumer:
Cela n'empêchera pas l'économiseur d'écran.
Le seul problème est qu'il s'écoulera 30 minutes après la fin du processus lorsque le système sera suspendu. C'est le cas de votre solution 'EDIT' également.
PS: Je cherchais une solution à un problème similaire lorsque j'ai découvert xdotool sur cette page. Donc merci. J'espère que cela t'aides.
Bien que EDIT 2 permette à l’économiseur d’écran de reprendre ses activités et de reprendre le service d’autosuspend lors de la suppression du fichier d’inhibition, comme indiqué ci-dessus, le système sera suspendu 30 minutes après la suppression du fichier.
Une solution possible consiste à désactiver l'économiseur d'écran intégré et les fonctionnalités de suspension automatique, à les implémenter nous-mêmes et à choisir le comportement du minuteur en fonction des besoins. La commande xprintidle (vous devrez peut-être l'installer) affiche le nombre de millisecondes pendant lequel aucune activité du clavier ou de la souris n'a été effectuée. Cela ouvre plusieurs possibilités. J'ai implémenté le gestionnaire d'inactivité suivant dans python (pas trop d'un script bash). Les fonctions incluent la définition de la commande, du délai d’expiration et du fichier d’inhibition (je l’ai appelé verrouiller) pour l’économiseur d’écran et/ou la suspension automatique. De plus, il est possible de choisir si le minuteur d'inactivité doit redémarrer lorsque le fichier d'inhibition est supprimé ou non (le comportement peut être différent pour la suspension et l'économiseur d'écran). J'ai essayé de préciser l'utilisation dans les notes, mais si quelque chose n'est pas clair, demandez-le.
#!/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()
Usage:
inactivitymanager &
à .profile ou .xsessionrc dans le répertoire de base (voyez lequel fonctionne pour vous. N'ajoutez pas dans les deux, sinon deux instances de ce script s'exécutent simultanément, quelque chose que je n'ai pas encore géré. Je suppose c’est dans ces détails que les principales implémentations prévalent sur les implémentations personnalisées).La façon dont le fichier inhibit y parvient est laissée à l’imagination de l’utilisateur pour le moment (si je me propose d’implémenter un démon pour cela, je le mettrai dans un EDIT pour cette réponse). Vous (OP) l'avez bien sûr résolu pour votre cas. Un écueil à éviter lors de la tentative d'interdiction de la suspension pour plusieurs processus est la suppression du fichier de verrouillage lorsqu'un processus se termine tandis qu'un autre est en cours d'exécution. Alternativement, le script peut être légèrement modifié pour empêcher la suspension si un fichier existe dans un répertoire particulier (un répertoire verrouillé). De cette façon, chaque processus peut avoir son propre fichier de verrouillage.
Remarques: