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 .
systemd
dokumentiert 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/binary
verwenden , 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.service
ausfü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 env
verwenden 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, wirdDISPLAY
Umgebungsvariable 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-control
für Konfigurationswerte, die den Ressourcenverbrauch einschränken könnten. Verwenden Siesystemctl show your-unit-unit.service
um die vollständigen Konfigurationswerte zu überprüfen, die den Dienst betreffen, den Sie zu starten versuchen. - Nicht interaktive Shell . Ihr
bash
Die CLI-Umgebung ist eine interaktive Login-Shell . Es hat Quelldateien wie.bashrc
dasssystemd
hat 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
sudo
verwenden undssh
erwarten, 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.service
dokumentiert , 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
systemd
hat eine sehr eingeschränkte Befehlszeilensyntax. Abhängig von Ihren Anforderungen können Sie die Shell-Syntax möglicherweise mitsystemd
replizieren 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?