Écriture d'un service systemd à exécuter à la reprise

15

mon ordinateur portable Dell est sujet à ce bogue avec le noyau 3.14. Comme solution de contournement, j'ai écrit un script simple

/ usr / bin / fix de luminosité:

#!/bin/bash

echo 0 > /sys/class/backlight/intel_backlight/brightnes

(et rendu exécutable chmod +x /usr/bin/brightness-fix)

et un service systemd l'appelant qui est exécuté au démarrage:

/etc/systemd/system/brightness-fix.service

[Unit]
Description=Fixes intel backlight control with Kernel 3.14

[Service]
Type=forking
ExecStart=/usr/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog
#RemainAfterExit=yes
#SysVStartPriority=99

[Install]
WantedBy=multi-user.target

et activé: systemctl enable /etc/systemd/system/brightness-fix.service

Cela fonctionne comme un charme et je peux contrôler la luminosité de mon écran comme je le souhaite. Le problème survient lorsque l'ordinateur portable reprend après être passé en mode veille (par exemple lors de la fermeture de la lèvre de l'ordinateur portable): le contrôle de la luminosité ne fonctionne plus sauf si j'exécute manuellement mon premier script ci-dessus:/usr/bin/brightness-fix

Comment puis-je créer un autre service systemd comme le mien ci-dessus à exécuter au moment de la reprise?

EDIT: Selon les commentaires ci-dessous, j'ai modifié mon brightness-fix.servicecomme ceci:

[Unit]
Description=Fixes intel backlight control with Kernel 3.14

[Service]
Type=oneshot
ExecStart=/usr/local/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=multi-user.target sleep.target

J'ai également ajouté echo "$1 $2" > /home/luca/br.logà mon script pour vérifier s'il est réellement exécuté. Le script est en fait également exécuté à resume ( post suspend) mais il n'a aucun effet (rétroéclairé à 100% et ne peut pas être modifié). J'ai également essayé de me connecter $DISPLAYet $USER, au moment de la reprise, ils sont vides. Donc, je suppose que le script est exécuté trop tôt au réveil. Un indice?

lviggiani
la source
2
WantedBy=sleep.target...
jasonwryan
Vraiment?! C'est si simple?! :) Puis-je ajouter 'sleep.target' à mon script ci-dessus ou dois-je créer un nouveau script de service systemd dédié pour cela?
lviggiani
... selon la documentation "Cette option peut être utilisée plusieurs fois, ou une liste de noms d'unités séparés par des espaces peut être fournie". Je vais essayer maintenant.
lviggiani
vous devez l' ajouter à votre fichier de service systemd existant (qui, soit dit en passant, n'est pas un script; c'est un fichier de configuration statique). et en guise de remarque, la norme de hiérarchie du système de fichiers indique que le bon endroit pour placer les scripts que vous avez écrits vous-même ne l'est /usr/local/binpas /usr/bin. ce répertoire est réservé au gestionnaire de packages uniquement.
strugee
2
Je crois que l'utilisation de l'appareil sleep.targetexécutera l'unité lorsque l'ordinateur sera en veille, plutôt que lorsqu'il reprendra. Voir ma réponse ci-dessous pour un fichier d'unité qui a fonctionné pour moi avec un problème similaire.
jat255

Réponses:

18

Je sais que c'est une vieille question, mais le fichier d'unité suivant a fonctionné pour moi pour exécuter un script à la sortie du sommeil:

[Unit]
Description=<your description>
After=suspend.target

[Service]
User=root
Type=oneshot
ExecStart=<your script here>
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=suspend.target

Je crois que c'est ce After=suspend.targetqui le fait fonctionner à la reprise, plutôt que lorsque l'ordinateur se met en veille.

jat255
la source
4
Fonctionne avec After=suspend.target dans l' unité et WantedBy=multi-user.target sleep.targetdans l' installation .
Emmanuel
J'utilise les unités suivantes avec succès ici sur Ubuntu 16.04 (élémentaire Loki).
Naftuli Kay
7

Comme alternative à l'écriture et à l'activation d'un fichier d'unité, vous pouvez également mettre un script shell (ou un lien symbolique vers votre script) dans /lib/systemd/system-sleep/.

Il sera appelé avant le sommeil / l'hibernation et au moment de la reprise.

De man systemd-suspend.service:

Immédiatement avant d'entrer en suspension du système et / ou en hibernation, systemd-suspend.service (et les autres unités mentionnées, respectivement) exécutera tous les exécutables dans / usr / lib / systemd / system-sleep / et leur passera deux arguments. Le premier argument sera "pre", le second soit "suspend", "hibernate", ou "hybrid-sleep" selon l'action choisie. Immédiatement après avoir quitté le système suspendre et / ou mettre en veille prolongée, les mêmes exécutables sont exécutés, mais le premier argument est maintenant "post". Tous les exécutables de ce répertoire sont exécutés en parallèle et l'exécution de l'action n'est pas poursuivie tant que tous les exécutables ne sont pas terminés.

Testez-le avec ceci:

#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

logger -t "test" "\$0=$0, \$1=$1, \$2=$2"
mivk
la source
La page de manuel que vous liez mentionne un fichier placé /usr/libmais tous vos exemples font référence à des fichiers sous/lib
qdii
@qdii: cela peut dépendre de la distribution et / ou de la version. Dans Debian 8 Jessie et Ubuntu 16.04, le system-sleeprépertoire semble être dans /lib/systemd/et /usr/lib/systemdcontient d'autres éléments.
mivk
1

Suivi de la réponse de mivk, dans laquelle j'évite de nettoyer avec un nouveau fichier d'unité (voir ma question ici Comment réagir aux événements de couvercle d'ordinateur portable? ). Voici ma solution; ce n'est pas simple à 100% ( soupir ) car le système n'est pas stable lorsqu'il sort du sommeil:

Sur ma boîte Fedora 26 j'ai mis un lien symbolique ici: /usr/lib/systemd/system-sleep/sleepyheadqui pointe ici :, /root/bin/sleepyheadqui contient:

#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

# This is called when the lid is closed, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=pre, $2=suspend
# ...and when the lid is opened, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=post, $2=suspend


touch /tmp/sleepyrun
logger -t "sleepyhead" "Start: \$1=$1, \$2=$2"
if [ "$1" = "post" ] ; then
    action="RUN trackpoint in background"
    bash /root/bin/trackpoint >/tmp/trackpoint-run 2>&1
else
    action="NO ACTION"
fi
logger -t "sleepyhead" "${action}: " "\$1=$1, \$2=$2"

Le /root/bin/trackpointscript suit. Notez que le premier sommeil est critique. L'appareil est configuré à chaque ouverture du couvercle, il n'existe donc pas au départ. Si j'essaie de faire autre chose que dormir, le script "sleepyhead" met très longtemps à sortir et mon pointeur sera figé pendant au moins 60 secondes. De plus, notez que vous ne pouvez pas mettre le /root/bin/trackpointscript en arrière-plan dans sleepyhead, ci-dessus. Si vous le faites, le processus sera tué à la sleepyheadsortie.

#!/bin/bash
# This is /root/bin/trackpoint

echo "Start $0"
date

found=false
dir=""
# dirlist can look like:
# /sys/devices/platform/i8042/serio1/serio25/speed
# /sys/devices/platform/i8042/serio1/serio24/speed
# ...the older one appears to get cleaned a little later.

sleep 1 # If I don't put this in here, my pointer locks up for a really long time...
for i in 1 2 3 4; do
    speedfiles=$(find /sys/devices/platform/i8042 -name speed) # There may be multiple speed files at this point.
    [ -z "$speedfiles" ] && { sleep 1; continue; }
    dirlist=$(dirname $speedfiles)
    printf "Speed file(s) at $(find /sys/devices/platform/i8042 -name speed | tail -1) \n"
    # All this remaking of the path is here because the filenames change with
    # every resume, and what's bigger: 9 or 10? ...Depends if you're
    # lexicographical or numerical. We need to always be numerical.
    largest_number="$(echo $dirlist | tr ' ' '\n' | sed -e 's/.*serio//' | sort -n | tail -1)"
    dir="$(echo $dirlist | tr ' ' '\n' | egrep serio${largest_number}\$ )"
    echo "Dir is $dir number is $largest_number" 
    [ -n "$dir" ] && found=true && break
done
$found || exit 1


date
echo -n 4 > $dir/inertia
echo -n 220 > $dir/sensitivity
echo -n 128 > $dir/speed
date
echo "Done $0"
Mike S
la source
Très bien organisé et documenté. Je vous donnerais plusieurs votes si je le pouvais!
MountainX-for-Monica