Zajímalo by mě, jaký je tento rozdíl mezi programy, které jsou; spuštěné pomocí systemd, když je povoleno prostřednictvím systemctl, oproti těm, které jsou spuštěny pomocí /etc/rc.local
nebo prostřednictvím CLI.
Nedávno jsem například používal shairport-sync pro raspberry pi. Zpočátku jsem nastavil shairport-sync tak, aby se spouštěl pomocí sudo systemctl povoleného shairport-sync.
Později jsem použil funkci v rámci shairport-sync
pro spouštění skriptů před připojením a odesílání do zařízení.
K mému překvapení byly skripty spuštěny pomocí shairport-sync
kill
arecord
nebo aplay
Když jsem však spustil skript přes terminál, skript se provedl a ukončil arecord
a aplay
.
Abych se ještě více zmátl, zabil jsem shairport-sync
a spustil to přes terminál, aby viděl výstup toho, co se dělo. Když jsem to udělal, skripty fungovaly tak, jak jsem očekával, když se zařízení připojilo a ukončilo arecord
a aplay
. Takže jako oprava jsem zakázal shairport-sync
v sysmtectl
a nastavte jej tak, aby se spouštěl v /etc/rc.local
jako rychlé řešení. Po reboot
fungovalo to, jak jsem očekával.
To mě vede k přesvědčení, že existuje určitý rozdíl mezi programem spuštěným odděleně od systemd
a program, který se spouští při spuštění přes /etc/rc.local
nebo CLI.
proč se to děje? Je to kvůli různým úrovním běhu? Nějaká temná magie?
Skript, který se spustí, když se zařízení připojí k shairport-sync
je následující: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
Zde je skript fade: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
Skript, který se spustí, když se zařízení odpojí od shairport-sync
je následující: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
V /var/log/syslog
jsem našel následující chybu pouze tehdy, když byl shairport-sync původně spuštěn odděleně od systemd
. Když shairport-sync
byl spuštěn z CLI nebo /etc/rc.local
nebyly přítomny žádné chyby.
Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
Upozorňujeme, že jediným rozdílem je způsob shairport-sync
se zpočátku spustí, když se zařízení připojí nebo odpojí shairport-sync
pokračuje v běhu.
Přijatá odpověď:
Variace „Proč se věci chovají jinak pod systemd?“ jsou často kladené otázky.
Kdykoli něco běží z CLI a ne ze systemd, existuje několik širokých kategorií možností, jak zohlednit rozdíly.
- Různé proměnné prostředí .
systemd
dokumentuje proměnné prostředí, které předává, vman systemd.exec
v sekci Proměnné prostředí ve spawnovaných procesech. Pokud chcete rozdíl zkontrolovat sami, můžete použítsystemd-run /path/to/binary
, spustí vaši aplikaci v přechodném rozsahu, protože by ji spouštěla služba systemd. Získáte výstup jako:Running as unit: run-u160.service
. Poté můžetejournalctl -u run-u160.service
zkontrolovat výstup. Upravte svou aplikaci tak, aby vypsala proměnné prostředí, které přijímá, a porovnejte běh CLI s během systemd. Pokud aplikace není vhodně upravena, stačí použítsystemd-run env
abyste viděli proměnné prostředí, které by byly předány, a zkontrolovali pro ně výsledné protokolování žurnálu. Pokud se pokoušíte spustit aplikaci X11 GUI,DISPLAY
je třeba nastavit proměnnou prostředí. V takovém případě zvažte použití funkce „autostart“ vašeho desktopového prostředí namístosystemd
. - Omezení zdrojů . Viz
man systemd.resource-control
pro konfigurační hodnoty, které by mohly omezit spotřebu zdrojů. Použijtesystemctl show your-unit-unit.service
zkontrolovat úplné konfigurační hodnoty ovlivňující službu, kterou se pokoušíte spustit. - Neinteraktivní prostředí . Váš
bash
Prostředí CLI je interaktivní přihlašovací shell . Má zdrojové soubory jako.bashrc
žesystemd
nemá. Kromě nastavení proměnných prostředí mohou tyto skripty provádět mnoho dalších věcí, jako je připojení agenta SSH, aby akce SSH nevyžadovaly přihlášení. Viz také Rozdíl mezi přihlašovacím a nepřihlašovacím prostředím? - Žádný TTY . Vaše interaktivní relace je připojena k TTY, kterou některé programy jako
sudo
assh
očekávejte při výzvě k zadání hesla. Viz také sudo:není přítomen tty a není zadán žádný program askpass - Relativní vs. Absolutní cesty . Relativní binární práce v shellu, ale jak je zdokumentováno v
man systemd.service
, první argument proExecStart=
musí být absolutní cestou k binárnímu souboru. - Omezená syntaxe příkazového řádku . Shell CLI podporují mnoho metaznaků, zatímco
systemd
má velmi omezenou syntaxi příkazového řádku. V závislosti na vašich potřebách můžete být schopni replikovat syntaxi Shell pomocísystemd
explicitním spuštěním příkazu přes shell:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
Je to funkce, díky které systém spouští váš kód v konzistentním prostředí s ovládacími prvky prostředků. To pomáhá s reprodukovatelnými a stabilními výsledky v dlouhodobém horizontu, aniž by došlo k přetížení hardwaru.
Související:Co tento proces STAT indikuje?