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.local
oder ü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-sync
nicht kill
arecord
oderaplay
Wenn ich das Skript jedoch über das Terminal ausführen würde, würde das Skript ausgeführt und getötet arecord
und aplay
.
Um mich weiter zu verwirren, habe ich es getötet shairport-sync
und ü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 arecord
und aplay
. So, wie ein Fix ich deaktiviert shairport-sync
in sysmtectl
und legen Sie es in laufen /etc/rc.local
als eine schnelle Lösung. Nach einem reboot
funktionierte es wie erwartet.
Dies lässt mich glauben, dass es einen Unterschied zwischen einem Programm gibt, das getrennt von ausgeführt wird, systemd
und einem Programm, das ausgeführt wird, wenn es über /etc/rc.local
oder ü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-sync
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 eine Verbindung zu einem Gerät getrennt wird, shairport-sync
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 /var/log/syslog
nur dann gefunden, wenn shairport-sync ursprünglich als getrennt von ausgeführt wurde systemd
. Wann shairport-sync
wurde von der CLI ausgeführt oder /etc/rc.local
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 der shairport-sync
Start gestartet wird, wenn Geräte verbunden oder getrennt werden shairport-sync
.
quelle
ps ... awk ... grep ...
Zeug könnte durch ein einfacheres ersetzt werdenpkill
/home/pi/shScripts/shairportfade.sh
?rc.local
Antworten:
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.
systemd
dokumentiert die Umgebungsvariablen, die übergeben werden, imman systemd.exec
Abschnitt Umgebungsvariablen in erzeugten Prozessen . Wenn Sie den Unterschied selbst untersuchen möchten, können Sie ihn verwendensystemd-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 dannjournalctl -u run-u160.service
die 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 einfachsystemd-run env
die übergebenen Umgebungsvariablen anzeigen und die resultierende Journalprotokollierung darauf überprüfen. Wenn Sie versuchen, eine X11-GUI-App zu starten, muss dieDISPLAY
Umgebungsvariable festgelegt werden. In diesem Fall sollten Sie die Funktion "Autostart" Ihrer Desktop-Umgebung anstelle von verwendensystemd
.man systemd.resource-control
Konfigurationswerte, die den Ressourcenverbrauch einschränken könnten. Verwenden Siesystemctl show your-unit-unit.service
diese Option , um die vollständigen Konfigurationswerte zu überprüfen, die sich auf den Dienst auswirken, den Sie starten möchten.bash
CLI-Umgebung ist eine interaktive Anmeldeshell . Es hat sourced Dateien wie.bashrc
dassystemd
nicht 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?sudo
undssh
erwarten, wenn sie nach Kennwörtern fragen. Siehe auch sudo: kein tty vorhanden und kein askpass-Programm angegebenman systemd.service
, muss das erste ArgumentExecStart=
ein absoluter Pfad zu einer Binärdatei sein.systemd
haben eine sehr eingeschränkte Befehlszeilensyntax . Abhängig von Ihren Anforderungen können Sie möglicherweise die Shell-Syntax replizieren,systemd
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 Ressourcensteuerungen ausführt. Dies hilft auf lange Sicht bei reproduzierbaren, stabilen Ergebnissen, ohne die Hardware zu überfordern.
quelle
sudo
Shell-Skript auf, das bessersudo shairportstart.sh
vom Terminal ausgeführt werden soll, da systemd das Skript als root ausführt und Sudo nicht als root ausgeführt werden muss./usr/bin/echo "mypassword" | /usr/bin/sudo /bin/pkill arecord
. Später heute werde ich versuchen, die Befehle und aus meinem Kill-Befehl zu entfernensudo
undecho
zu prüfen, ob dies zu denselben Ergebnissen führt. Ich vermute, dass dies funktionieren wird, da der Fehler anscheinend dadurch verursacht wurde, dass mit demsudo
Befehl kein Kennwort gesendet wurde . Vielen Dank für die Hilfe beim Verständnis, warum es einen Unterschied zwischensystemd
und der CLI gibt