Schreiben eines systemd-Dienstes, der beim Fortsetzen ausgeführt werden soll

15

Auf meinem Dell-Laptop tritt dieser Fehler mit Kernel 3.14 auf. Als Workaround habe ich ein einfaches Skript geschrieben

/ usr / bin / Brightness-Fix:

#!/bin/bash

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

(und ausführbar gemacht: chmod +x /usr/bin/brightness-fix)

und ein systemd-Dienst, der es aufruft und beim Start ausgeführt wird:

/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

und aktiviert: systemctl enable /etc/systemd/system/brightness-fix.service

Das funktioniert wie ein Zauber und ich kann die Helligkeit meines Displays wie gewünscht steuern. Das Problem tritt auf, wenn der Laptop nach dem Ruhezustand wieder in Betrieb genommen wird (z. B. beim Schließen der Lippe des Laptops): Die Helligkeitsregelung funktioniert nicht mehr, es sei denn, ich führe das obige erste Skript manuell aus:/usr/bin/brightness-fix

Wie kann ich einen anderen systemd-Dienst wie meinen oben erstellen, der zur Wiederaufnahme ausgeführt wird?

BEARBEITEN: Laut Kommentaren unten habe ich meine brightness-fix.servicewie folgt geändert :

[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

Außerdem habe ich echo "$1 $2" > /home/luca/br.logmein Skript erweitert, um zu überprüfen, ob es tatsächlich ausgeführt wird. Das Skript, das es tatsächlich ausführt, wird auch beim Fortsetzen ausgeführt (post suspend ) ausgeführt, hat aber keine Auswirkung (Hintergrundbeleuchtung ist 100% und kann nicht geändert werden). Ich habe auch versucht, zu protokollieren, $DISPLAYund zum $USERZeitpunkt der Wiederaufnahme sind sie leer. Ich vermute also, dass das Skript beim Aufwachen aus dem Schlaf zu früh ausgeführt wird. Irgendein Hinweis?

lviggiani
quelle
2
WantedBy=sleep.target...
Jasonwryan
Ja wirklich?! Ist das so einfach ?! :) Kann ich 'sleep.target' zu meinem obigen Skript hinzufügen oder soll ich ein neues dediziertes systemd-Dienstskript dafür erstellen?
Lviggiani
... laut Dokumentation "Diese Option kann mehrmals verwendet werden, oder es kann eine durch Leerzeichen getrennte Liste von Gerätenamen angegeben werden". Ich werde es jetzt versuchen.
Lviggiani
Sie müssen es zu Ihrer vorhandenen systemd-Servicedatei hinzufügen (die übrigens kein Skript ist, sondern eine statische Konfigurationsdatei). und als Randnotiz gibt der Dateisystem-Hierarchie-Standard an, dass der richtige Ort zum Ablegen von Skripten, die Sie selbst geschrieben haben /usr/local/bin, nicht der ist /usr/bin. Dieses Verzeichnis ist nur für den Paketmanager reserviert.
Strugee
2
Ich glaube, mit dem sleep.targetwird das Gerät ausgeführt, wenn der Computer in den Energiesparmodus wechselt, und nicht, wenn es fortgesetzt wird. In meiner Antwort unten finden Sie eine Unit-Datei, die bei mir mit einem ähnlichen Problem funktioniert hat.
jat255

Antworten:

17

Ich weiß, dass dies eine alte Frage ist, aber die folgende Unit-Datei hat mir geholfen, ein Skript auszuführen, wenn ich aus dem Ruhezustand zurückgekehrt bin:

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

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

[Install]
WantedBy=suspend.target

Ich glaube, es ist das After=suspend.target, was es auf Resume laufen lässt, anstatt wenn der Computer in den Ruhezustand geht.

jat255
quelle
4
Funktioniert mit After=suspend.target in Unit und WantedBy=multi-user.target sleep.targetin Install .
Emmanuel
Ich benutze die folgenden Einheiten erfolgreich hier auf Ubuntu 16.04 (elementare Loki).
Naftuli Kay
7

Alternativ zum Schreiben und Aktivieren einer Unit-Datei können Sie auch ein Shell-Skript (oder einen Symlink zu Ihrem Skript) einfügen /lib/systemd/system-sleep/.

Es wird vor dem Schlafengehen / Ruhezustand und zur Wiederaufnahme der Arbeit aufgerufen.

Von man systemd-suspend.service:

Unmittelbar vor dem Aufrufen von system suspend und / oder hibernation führt systemd-suspend.service (bzw. die anderen genannten Einheiten) alle ausführbaren Dateien in / usr / lib / systemd / system-sleep / aus und übergibt ihnen zwei Argumente. Das erste Argument ist "pre", das zweite "suspend", "hibernate" oder "hybrid-sleep", abhängig von der gewählten Aktion. Unmittelbar nach dem Beenden des System-Suspend- und / oder Ruhezustands werden dieselben ausführbaren Dateien ausgeführt, aber das erste Argument lautet jetzt "post". Alle ausführbaren Dateien in diesem Verzeichnis werden parallel ausgeführt, und die Ausführung der Aktion wird erst fortgesetzt, wenn alle ausführbaren Dateien abgeschlossen sind.

Testen Sie es mit diesem:

#!/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
quelle
Die Manpage, auf die Sie verlinken, erwähnt eine Datei, in der Sie sie abgelegt haben. /usr/libAlle Beispiele beziehen sich jedoch auf Dateien unter/lib
qdii
@qdii: Dies kann von der Distribution und / oder Version abhängen. In Debian 8 Jessie und Ubuntu 16.04 system-sleepscheint sich das Verzeichnis in zu befinden /lib/systemd/und /usr/lib/systemdenthält andere Sachen.
mivk
1

Follow-up zur Antwort von mivk, bei der ich es vermeide, mit einer neuen Gerätedatei herumzuspielen (siehe meine Frage hier Wie kann ich auf Ereignisse auf dem Laptopdeckel reagieren? ). Hier ist meine Lösung; Es ist nicht 100% einfach ( seufz ), weil das System nicht stabil ist, wenn es aus dem Schlaf kommt:

Auf meiner Fedora 26 Box habe ich hier einen Symlink gesetzt: /usr/lib/systemd/system-sleep/sleepyheadwelche Punkte hier :, /root/bin/sleepyheadwelche enthalten:

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

Das /root/bin/trackpointSkript folgt. Beachten Sie, dass der erste Schlaf kritisch ist. Das Gerät wird bei jedem Öffnen des Deckels eingerichtet, sodass es zunächst nicht vorhanden ist. Wenn ich versuche, etwas anderes als den Schlaf zu tun, dauert das Beenden des Skripts "sleepyhead" sehr lange und mein Zeiger wird für mindestens 60 Sekunden eingefroren. Beachten Sie außerdem, dass Sie das /root/bin/trackpointSkript nicht oben im Hintergrund platzieren sleepyheadkönnen. Wenn Sie dies tun, wird der Prozess beim sleepyheadBeenden abgebrochen.

#!/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
quelle
Sehr gut organisiert und dokumentiert. Ich würde Ihnen mehrere Stimmen geben, wenn ich könnte!
MountainX für Monica Cellio