Unterschied zwischen systemd und terminal startprogramm

9

Ich bin gespannt, was dieser Unterschied zwischen Programmen ist, die sind; wurde mit systemd gestartet, wenn es über systemctl aktiviert wurde, im Vergleich zu denen, die mit /etc/rc.localoder über die CLI gestartet wurden .

Zum Beispiel habe ich kürzlich Shairport-Sync für den Himbeer-Pi verwendet. Zunächst habe ich shairport-sync so eingestellt, dass es mit sudo systemctl-fähiger shairport-sync startet.

Später verwendete ich eine Funktion shairport-sync, um Skripte vor und nach dem Verbinden auf Geräten auszuführen.

Zu meiner Überraschung haben die Skripte bei der Ausführung von shairport-syncnicht kill arecordoderaplay

Wenn ich das Skript jedoch über das Terminal ausführen würde, würde das Skript ausgeführt und getötet arecordund aplay.

Um mich weiter zu verwirren, habe ich es getötet shairport-syncund über das Terminal gestartet, um die Ausgabe des Geschehens zu sehen. Als ich das tat, funktionierten die Skripte wie erwartet, als das Gerät verbunden und getötet wurde arecordund aplay. So, wie ein Fix ich deaktiviert shairport-syncin sysmtectlund legen Sie es in laufen /etc/rc.localals eine schnelle Lösung. Nach einem rebootfunktionierte es wie erwartet.

Dies lässt mich glauben, dass es einen Unterschied zwischen einem Programm gibt, das getrennt von ausgeführt wird, systemdund einem Programm, das ausgeführt wird, wenn es über /etc/rc.localoder über die CLI gestartet wird .

Warum passiert das? Liegt das an unterschiedlichen Laufstufen? Dunkle Magie?

Das Skript, das ausgeführt wird, wenn ein Gerät eine Verbindung herstellt, shairport-synclautet wie folgt:shairportstart.sh

#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
        /usr/bin/amixer set Speaker 40%
else
        /usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&

exit 0

Hier ist das Fade-Skript: shairportfade.sh

#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do  
    /usr/bin/amixer set Speaker 1+
done
exit 0

Das Skript, das ausgeführt wird, wenn eine Verbindung zu einem Gerät getrennt wird, shairport-synclautet wie folgt:shairportend.sh

#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0

Ich habe den folgenden Fehler /var/log/syslognur dann gefunden, wenn shairport-sync ursprünglich als getrennt von ausgeführt wurde systemd. Wann shairport-syncwurde von der CLI ausgeführt oder /etc/rc.locales waren keine Fehler vorhanden.

Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified

Bitte beachten Sie, dass der einzige Unterschied darin besteht, wie der shairport-syncStart gestartet wird, wenn Geräte verbunden oder getrennt werden shairport-sync.

Brett Reinhard
quelle
1
Das ps ... awk ... grep ...Zeug könnte durch ein einfacheres ersetzt werdenpkill
am
@thrig Ursprünglich war die Zeile viel einfacher, aber da sie nicht funktionierte, dachte ich, ich hätte versucht, die Instanz mit anderen Methoden zu beenden, was immer noch nicht funktionierte. Das Beenden des Prozesses war nicht das Problem an sich, da es funktionierte, sondern nur, wenn es von einem Benutzer-Login ausgeführt wurde
Brett Reinhard
Können Sie die Liste von anzeigen /home/pi/shScripts/shairportfade.sh?
Michael D.
@ MichaelD. Ich habe das Fade-Skript sowie das Skript hinzugefügt, das ausgeführt wird, wenn ein Gerät die Verbindung zur Shairport-Synchronisierung trennt
Brett Reinhard
@BrettReinhard, was ist das Problem mit dem Ausführen des Skripts vonrc.local
Michael D.

Antworten:

17

Variationen von "Warum verhalten sich die Dinge unter systemd anders?" sind eine häufig gestellte Frage.

Jedes Mal, wenn etwas von der CLI und nicht von systemd ausgeführt wird, gibt es einige breite Kategorien von Möglichkeiten, um Unterschiede zu berücksichtigen.

  1. Verschiedene Umgebungsvariablen . systemddokumentiert die Umgebungsvariablen, die übergeben werden, im man systemd.execAbschnitt Umgebungsvariablen in erzeugten Prozessen . Wenn Sie den Unterschied selbst untersuchen möchten, können Sie ihn verwenden systemd-run /path/to/binary. Ihre App wird in einem vorübergehenden Bereich ausgeführt, wie er von einem systemd-Dienst ausgeführt wird. Sie erhalten folgende Ausgabe : Running as unit: run-u160.service. Sie können dann journalctl -u run-u160.servicedie Ausgabe überprüfen. Ändern Sie Ihre App, um die empfangenen Umgebungsvariablen auszugeben und den CLI-Lauf mit dem systemd-Lauf zu vergleichen. Wenn die App nicht bequem geändert werden kann, können Sie einfach systemd-run envdie übergebenen Umgebungsvariablen anzeigen und die resultierende Journalprotokollierung darauf überprüfen. Wenn Sie versuchen, eine X11-GUI-App zu starten, muss die DISPLAYUmgebungsvariable festgelegt werden. In diesem Fall sollten Sie die Funktion "Autostart" Ihrer Desktop-Umgebung anstelle von verwenden systemd.
  2. Ressourcenbeschränkungen . Siehe man systemd.resource-controlKonfigurationswerte, die den Ressourcenverbrauch einschränken könnten. Verwenden Sie systemctl show your-unit-unit.servicediese Option , um die vollständigen Konfigurationswerte zu überprüfen, die sich auf den Dienst auswirken, den Sie starten möchten.
  3. Nicht interaktive Shell . Ihre bashCLI-Umgebung ist eine interaktive Anmeldeshell . Es hat sourced Dateien wie .bashrcdas systemdnicht hat. Neben dem Festlegen von Umgebungsvariablen können diese Skripts eine Reihe anderer Aufgaben ausführen, z. B. das Verbinden eines SSH-Agenten, sodass für SSH-Aktionen keine Anmeldung erforderlich ist. Siehe auch Unterschied zwischen Login-Shell und Nicht-Login-Shell?
  4. Kein TTY . Ihre interaktive Sitzung ist mit einem TTY verbunden, den einige Programme mögen sudound ssherwarten, wenn sie nach Kennwörtern fragen. Siehe auch sudo: kein tty vorhanden und kein askpass-Programm angegeben
  5. Relative vs. absolute Pfade . Relative Binärarbeit in der Shell, aber wie in dokumentiertman systemd.service , muss das erste Argument ExecStart=ein absoluter Pfad zu einer Binärdatei sein.
  6. Eingeschränkte Befehlszeilensyntax . Shell-CLIs unterstützen viele Metazeichen und systemdhaben eine sehr eingeschränkte Befehlszeilensyntax . Abhängig von Ihren Anforderungen können Sie möglicherweise die Shell-Syntax replizieren, systemdindem Sie Ihren Befehl explizit über eine Shell ausführen:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'

Es ist eine Funktion, mit der das System Ihren Code in einer konsistenten Umgebung mit Ressourcensteuerungen ausführt. Dies hilft auf lange Sicht bei reproduzierbaren, stabilen Ergebnissen, ohne die Hardware zu überfordern.

Mark Stosberg
quelle
Außerdem müssen MAC-Kontext (SELinux, ...), Funktionen, Namespaces ... berücksichtigt werden
Bigon
2
@BrettReinhard Rufen Sie kein sudoShell-Skript auf, das besser sudo shairportstart.shvom Terminal ausgeführt werden soll, da systemd das Skript als root ausführt und Sudo nicht als root ausgeführt werden muss.
Michael D.
1
Ich habe mein Problem auf verschiedene Weise gelöst, um zu verstehen, was geschah. Letztendlich änderte ich meinen Kill-Befehl in /usr/bin/echo "mypassword" | /usr/bin/sudo /bin/pkill arecord. Später heute werde ich versuchen, die Befehle und aus meinem Kill-Befehl zu entfernen sudound echozu prüfen, ob dies zu denselben Ergebnissen führt. Ich vermute, dass dies funktionieren wird, da der Fehler anscheinend dadurch verursacht wurde, dass mit dem sudoBefehl kein Kennwort gesendet wurde . Vielen Dank für die Hilfe beim Verständnis, warum es einen Unterschied zwischen systemdund der CLI gibt
Brett Reinhard
1
Ein weiterer Unterschied, der offensichtlich sein mag, der mich heute jedoch beeindruckt hat, besteht darin, dass systemd versucht, den Status eines Dienstes zu verfolgen, und ihn nicht startet, wenn es glaubt, dass er bereits aktiv ist, und daher möglicherweise nicht einmal ein init.d-Skript startet, wenn Es glaubt, dass der Dienst ausgeführt wird. Im Gegensatz dazu werden init.d-Skripte normalerweise geschrieben, um den Dienst immer zu überprüfen und entsprechend zu starten.
Josh Kelley
1
@ JoshKelley Danke für den Tipp. Dies ist kein Unterschied zwischen systemd und der CLI, sondern zwischen systemd- und sysVinit init.d-Skripten.
Mark Stosberg