Ich bin neugierig, was dieser Unterschied zwischen Programmen ist, die; mit systemd gestartet, wenn es durch systemctl aktiviert wurde, im Vergleich zu denen, die mittels /etc/rc.local gestartet wurden oder über die CLI.
Zum Beispiel habe ich kürzlich shairport-sync für den Himbeer-Pi verwendet. Anfangs habe ich shairport-sync so eingestellt, dass es mit sudo systemctl enabled shairport-sync gestartet wird.
Später habe ich eine Funktionalität in shairport-sync verwendet um Skripte vorab auszuführen und an Geräte zu senden, die eine Verbindung herstellen.
Zu meiner Überraschung werden die Skripte von shairport-sync ausgeführt hat nicht kill arecord oder aplay
Wenn ich das Skript jedoch über das Terminal ausführen würde, wurde das Skript ausgeführt und arecord beendet und aplay .
Um mich noch mehr zu verwirren, habe ich shairport-sync beendet und startete es über das Terminal, um die Ausgabe dessen zu sehen, was passiert ist. Als ich dies tat, funktionierten die Skripte so, wie ich es erwartet hatte, als das Gerät eine Verbindung herstellte und arecord beendete und aplay . Als Fix habe ich also shairport-sync deaktiviert in sysmtectl und stellen Sie es so ein, dass es in /etc/rc.local ausgeführt wird als schnelle Lösung. Nach einem reboot es funktionierte so, wie ich es erwartet hatte.
Dies lässt mich glauben, dass es einen Unterschied zwischen einem Programm gibt, das als Teil von systemd ausgeführt wird und ein Programm, das ausgeführt wird, wenn es über /etc/rc.local gestartet wird oder die CLI.
Warum passiert das? Liegt das an unterschiedlichen Runlevels? Etwas dunkle Magie?
Das Skript, das ausgeführt wird, wenn ein Gerät eine Verbindung zu shairport-sync herstellt lautet 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 ein Gerät die Verbindung zu shairport-sync trennt lautet 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 in /var/log/syslog gefunden nur wenn shairport-sync ursprünglich als Teil von systemd ausgeführt wurde . Wenn shairport-sync wurde über die CLI oder /etc/rc.local ausgeführt es 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 shairport-sync wird initial gestartet, wenn Geräte shairport-sync verbinden oder trennen läuft weiter.
Akzeptierte Antwort:
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.
- Verschiedene Umgebungsvariablen .
systemddokumentiert die Umgebungsvariablen, die es inman systemd.execübergibt im Abschnitt Umgebungsvariablen in erzeugten Prozessen. Wenn Sie den Unterschied selbst überprüfen möchten, können Siesystemd-run /path/to/binaryverwenden , wird Ihre App in einem vorübergehenden Bereich ausgeführt, als würde sie von einem systemd-Dienst ausgeführt werden. Sie erhalten eine Ausgabe wie:Running as unit: run-u160.service. Sie können dannjournalctl -u run-u160.serviceausführen um die Ausgabe zu überprüfen. Ändern Sie Ihre App, um die empfangenen Umgebungsvariablen auszugeben, und vergleichen Sie die CLI-Ausführung mit der systemd-Ausführung. Wenn die App nicht bequem geändert werden kann, können Sie einfachsystemd-run envverwenden um die Umgebungsvariablen anzuzeigen, die übergeben würden, und die resultierende Journalprotokollierung darauf zu überprüfen. Wenn Sie versuchen, eine X11-GUI-App zu starten, wirdDISPLAYUmgebungsvariable muss gesetzt werden. Erwägen Sie in diesem Fall die Verwendung der „Autostart“-Funktion Ihrer Desktop-Umgebung anstelle vonsystemd. - Ressourcenbeschränkungen . Siehe
man systemd.resource-controlfür Konfigurationswerte, die den Ressourcenverbrauch einschränken könnten. Verwenden Siesystemctl show your-unit-unit.serviceum die vollständigen Konfigurationswerte zu überprüfen, die den Dienst betreffen, den Sie zu starten versuchen. - Nicht interaktive Shell . Ihr
bashDie CLI-Umgebung ist eine interaktive Login-Shell . Es hat Quelldateien wie.bashrcdasssystemdhat nicht. Neben dem Festlegen von Umgebungsvariablen können diese Skripte noch viele andere Dinge tun, 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? - Kein TTY . Ihre interaktive Sitzung ist mit einem TTY verbunden, das einige Programme wie
sudoverwenden undssherwarten, wenn Sie zur Eingabe von Passwörtern aufgefordert werden. Siehe auch sudo:kein tty vorhanden und kein askpass-Programm angegeben - Relative vs. Absolute Pfade . Relative Binärarbeit in der Shell, aber wie in
man systemd.servicedokumentiert , das erste Argument fürExecStart=muss ein absoluter Pfad zu einer Binärdatei sein. - Eingeschränkte Befehlszeilensyntax . Shell-CLIs unterstützen viele Metazeichen, während
systemdhat eine sehr eingeschränkte Befehlszeilensyntax. Abhängig von Ihren Anforderungen können Sie die Shell-Syntax möglicherweise mitsystemdreplizieren indem 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 Ressourcensteuerung ausführt. Dies hilft bei reproduzierbaren, stabilen Ergebnissen auf lange Sicht, ohne die Hardware zu überlasten.
Verwandte:Was zeigt dieser Prozess STAT an?