Bash Skript vor dem Sleep Modus ausführen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
macedes
Beiträge: 10
Registriert: 30.06.2013 17:45:48

Bash Skript vor dem Sleep Modus ausführen

Beitrag von macedes » 06.05.2016 13:19:29

Hallo zusammen, ich hab einen Skript geschrieben, dass die Funksteckdosen steuern kann.
Pfad: /home/user/Skripte/speaker.sh off

Das skript soll vor dem Schlafmodus ausgeführt werden. Dafür habe ich im Internet lesen können, dass ich über systemd einen Service schreiben muss:
Pfad: /etc/systemd/system/suspend.service

Inhalt:

Code: Alles auswählen

[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=%I
Type=simple
Environment=DISPLAY=:0
ExecStart=/home/geveci/Skripte/speaker.sh off

[Install]
WantedBy=sleep.target
Leider funktioniert das nicht. Wenn ich mit dem Befehl "systemctl status suspend.service" den status abfrage, dann erhalte ich die folgende Meldung:

suspend.service - User suspend actions
Loaded: loaded (/etc/systemd/system/suspend.service; enabled)
Active: failed (Result: exit-code) since Fr 2016-05-06 13:05:37 CEST; 1min 51s ago
Process: 15297 ExecStart=/home/geveci/Skripte/speaker.sh off (code=exited, status=217/USER)
Main PID: 15297 (code=exited, status=217/USER)

Was mache ich falsch? Kann mir jemand helfen?
Vielen Dank schonmal im Vorraus.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash Skript vor dem Sleep Modus ausführen

Beitrag von rendegast » 06.05.2016 14:26:31

Das Skript wird von systemd ausgeführt,
also mit dessen Rechten und Environment.
(Also ist es erstmal generell keine gute Idee,
eine dem User zugängliche Ressource einem Root-Prozess zuzuführen.
Also das Skript als writeonly-root in zBsp. /usr/local/bin/,
oder dem Service irgendwie ein change-user beibringen)

Um das Environment zu bestimmen, zBsp. mal sowas

Code: Alles auswählen

#ExecStart=/home/geveci/Skripte/speaker.sh off
ExecStart=set > /var/tmp/systemd-set
(wegen der Umleitung: Eventuell so nicht erlaubt, daher vielleicht in ein Skript auslagern)
Also zBsp. bzgl. benutzter Pfade im Skript.

Weiterhin, ist speaker.sh irgendwie grafisch?
Denn auf die X-Session des Benutzers hätte systemd auch nicht ohne weiteres Zugriff.



Als Test vielleicht mal in einer virtuellen Konsole das Skript aufrufen

Code: Alles auswählen

STRG-ALT-F1
.... root einloggen ...
# /home/geveci/Skripte/speaker.sh off ; echo $?
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

TomL

Re: Bash Skript vor dem Sleep Modus ausführen

Beitrag von TomL » 06.05.2016 15:22:34

Mir sind auf Anhieb 2 (wahrscheinliche) Fehler aufgefallen:
  • Die Instance-Variable %I kann bei diesem Unit-Namen 'suspend.service' nicht verwendet werden... das heisst, da sie nur bei "instantiated units" gesetzt ist, enthält die entweder gar nix oder irgendwas - siehe '@'. Besser wäre es, den User-Namen direkt einzutragen.
  • Wenn ich das richtig deute, fehlt der Exit-Code 0 (bedeutet "Erfolgreich") des Scripts. Das heisst, das Script muss einen Exit-Code haben, damit systemd in oder von dessen Abhängigkeit weitermachen kann.
BTW, das Script sollte nicht im User-Home-Dir liegen, sondern besser von root für den User gestartet werden und mit "rw" nur für root in /usr/local/bin liegen

Bei mir funktioniert diese Unit nach dem CLI-Command "systemctl suspend" problemlos.... wobei ich hier zum Testen nur einen Log-Eintrag generiere:

Code: Alles auswählen

[Unit]
Description=Prepare System Sleep

[Service]
Type=oneshot
User=thomas
ExecStart=/usr/local/bin/LogEntry "going to bed with User=%u"

[Install]
RequiredBy=suspend.target
Um Deine Unit "verändert" zu aktivieren, empfehle ich zuerst einmal einen disable und dann einen neuen enable, damit die Symlinks in den Targets korrekt gesetzt werden... sonst wartest Du vielleicht bis Weihnachten darauf, dass es funktioniert und wunderst Dich, warum es nicht klappt. Ein simpler "daemon reload" ändert nämlich nicht die Symlinks.

macedes
Beiträge: 10
Registriert: 30.06.2013 17:45:48

Re: Bash Skript vor dem Sleep Modus ausführen

Beitrag von macedes » 06.05.2016 22:43:33

Ich habe das Skript jetzt in den usr/local/bin Ordner kopiert und den suspend.service wie folgt umgeschrieben:

Code: Alles auswählen

[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=eray
Type=oneshot
ExecStart=/usr/local/bin/speaker.sh off

[Install]
RequiredBy=suspend.target

Wenn ich jetzt den Status abfrage, dann erhalte ich die folgende Meldung:
systemctl status -l suspend.service
● suspend.service - User suspend actions
Loaded: loaded (/etc/systemd/system/suspend.service; enabled)
Active: failed (Result: exit-code) since Fr 2016-05-06 22:35:03 CEST; 3min 40s ago
Process: 18520 ExecStart=/usr/local/bin/speaker.sh off (code=exited, status=255)
Main PID: 18520 (code=exited, status=255)

Mein Bash Skript sieht wie folgt aus:

Code: Alles auswählen

#!/bin/sh
case "$@" in 
        on)
                logger speaker is turning on
                ssh pi@192.168.2.102 'sudo ~/raspberry-remote/./send 11111 1 1'
        ;;
        off)
                logger speaker is turning off
                ssh pi@192.168.2.102 'sudo ~/raspberry-remote/./send 11111 1 0'
        ;;
esac
exit

Liegt es vielleicht an der ssh Verbindung?

TomL

Re: AW: Bash Skript vor dem Sleep Modus ausführen

Beitrag von TomL » 06.05.2016 23:56:30

Wie ich schon sagte... der exit-Code fehlt. Beende das Script mit exit 0, wenn es erfolgreich war und mit exit 1 bei Fehlern. Dann weiss Systemd auch wie es weitergeht.... denn so (ohne exit-code) betrachtet Systemd dein script als gescheitert.

Btw, bei solchen Namen wie "suspend.service" solltest du besser vorsichtig sein ... denn der liegt voll im Bereich der möglichen systemd-eigenen Namen. ... deshalb besser doppelt kontrollieren, oder nen Zusatz wie "my-" verwenden ... oder einfach drauf vertrauen, dass es jetzt und über-über-übermorgen immer noch gut geht.

macedes
Beiträge: 10
Registriert: 30.06.2013 17:45:48

Re: Bash Skript vor dem Sleep Modus ausführen

Beitrag von macedes » 07.05.2016 07:44:44

Jetzt habe ich festgestellt, dass die Netzwerkverbindung beim aktivieren vom Schlafmodus die Netzwerkverbindung anscheinend nicht mehr besteht. Kann ich das irgendwie verhindern?

speaker.sh[20171]: ssh: connect to host 192.168.2.102 port 22: Network is unreachable

TomL

Re: Bash Skript vor dem Sleep Modus ausführen

Beitrag von TomL » 07.05.2016 10:31:20

Das ist zugegebenermaßen ein unschönes Problem, aber meines Erachtens nach leider auch ein bekanntes Problem. Wenn Du einen Netzwerkmanager nutzt, der via init.d-Script gestartet wird, kann es sein, dass der sich nicht so richtig wirklich gut in die systemd-Landschaft einfügt.... der macht einfach sein Ding und schert sich nicht um Abhängigkeiten. Und wenn er meint, jetzt wärs Zeit die Netzwerkverbindung zu killen, dann tut er das einfach.

Es gibt jetzt mehrere Möglichkeiten:
1. Du könntest mit einem /etc/NetworkManager/dispatcher.d/pre-down.d-Script experimentieren. Vielleicht startet er das auch beim suspend.
2. Du entfernst den Netwerkmanager und richtest das Netzwerk via systemd ein, was meiner Meinung nach auch die Zukunft ist

Und weil ich irgendwo hier im Text "raspberry" gelesen habe, empfehle ich, das Netzwerk sowieso über systemd einzurichten. Ein Netzwerkmanager ist völlig unnötig, wenn das Netz eh nie wechseln wird.

Antworten