Sono curioso di sapere quale sia questa differenza tra i programmi che sono; avviato con systemd quando abilitato tramite systemctl, rispetto a quelli avviati tramite /etc/rc.local
o tramite la CLI.
Ad esempio, di recente stavo usando shairport-sync per il raspberry pi. Inizialmente, ho impostato shairport-sync per l'avvio tramite sudo systemctl abilitato shairport-sync.
Successivamente ho utilizzato una funzionalità all'interno di shairport-sync
per eseguire gli script prima e postarli sui dispositivi che si connettono.
Con mia sorpresa, gli script vengono eseguiti da shairport-sync
non ha kill
arecord
o aplay
Tuttavia, quando eseguivo lo script tramite terminale, lo script veniva eseguito e ucciso arecord
e aplay
.
Per confondermi ulteriormente, ho ucciso shairport-sync
e l'ho avviato tramite terminale per vedere l'output di ciò che stava accadendo. Quando l'ho fatto, gli script hanno funzionato come mi aspettavo quando il dispositivo si è connesso e ha ucciso arecord
e aplay
. Quindi, come soluzione, ho disabilitato shairport-sync
in sysmtectl
e impostalo per l'esecuzione in /etc/rc.local
come una soluzione rapida. Dopo un reboot
ha funzionato come mi aspettavo.
Questo mi porta a credere che ci sia una certa differenza tra un programma eseguito come separato da systemd
e un programma che viene eseguito all'avvio tramite /etc/rc.local
o l'interfaccia a riga di comando.
Perché questo accade? È a causa di diversi livelli di esecuzione? Un po' di magia oscura?
Lo script che viene eseguito quando un dispositivo si connette a shairport-sync
è il seguente: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
Ecco lo script di dissolvenza: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
Lo script che viene eseguito quando un dispositivo si disconnette a shairport-sync
è il seguente: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
Ho trovato il seguente errore in /var/log/syslog
solo quando shairport-sync è stato inizialmente eseguito come separato da systemd
. Quando shairport-sync
è stato eseguito dalla CLI o da /etc/rc.local
non sono presenti errori.
Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
Tieni presente che l'unica differenza è come shairport-sync
viene avviato inizialmente, quando i dispositivi si connettono o disconnettono shairport-sync
continua a funzionare.
Risposta accettata:
Variazioni di "Perché le cose si comportano diversamente in systemd?" sono una domanda frequente.
Ogni volta che qualcosa viene eseguito dalla CLI e non da systemd, ci sono alcune ampie categorie di possibilità per tenere conto delle differenze.
- Variabili di ambiente diverse .
systemd
documenta le variabili di ambiente che passa inman systemd.exec
nella sezione Variabili d'ambiente nei processi generati. Se vuoi controllare tu stesso la differenza, puoi usaresystemd-run /path/to/binary
, eseguirà la tua app in un ambito transitorio, poiché verrebbe eseguita da un servizio systemd. Otterrai un output come:Running as unit: run-u160.service
. Puoi quindijournalctl -u run-u160.service
per rivedere l'output. Modifica la tua app per scaricare le variabili di ambiente che riceve e confrontare l'esecuzione della CLI con l'esecuzione di systemd. Se l'app non viene modificata in modo conveniente, puoi semplicemente utilizzaresystemd-run env
per vedere le variabili di ambiente che verrebbero passate e rivedere la registrazione del journal risultante. Se stai tentando di avviare un'app GUI X11, ilDISPLAY
è necessario impostare la variabile di ambiente. In tal caso, considera l'utilizzo della funzione di "avvio automatico" del tuo ambiente desktop invece disystemd
. - Restrizioni sulle risorse . Vedi
man systemd.resource-control
per i valori di configurazione che potrebbero limitare il consumo di risorse. Usasystemctl show your-unit-unit.service
per controllare i valori di configurazione completi che interessano il servizio che stai tentando di avviare. - Shell non interattiva . Il tuo
bash
L'ambiente CLI è una shell di accesso interattiva . Ha file di origine come.bashrc
quelsystemd
non ha. Oltre a impostare le variabili di ambiente, questi script possono eseguire un numero qualsiasi di altre cose, come la connessione di un agente SSH in modo che le azioni SSH non richiedano un accesso. Vedi anche Differenza tra Shell di accesso e Shell non di accesso? - Nessun TTY . La tua sessione interattiva è collegata a un TTY che alcuni programmi come
sudo
essh
aspettarsi quando si richiedono le password. Vedi anche sudo:no tty present e nessun programma askpass specificato - Percorsi relativi e assoluti . Il relativo lavoro binario nella shell, ma come documentato in
man systemd.service
, il primo argomento diExecStart=
deve essere un percorso assoluto di un file binario. - Sintassi della riga di comando limitata . Le CLI della shell supportano molti metacaratteri, mentre
systemd
ha una sintassi della riga di comando molto ristretta. A seconda delle tue esigenze, potresti essere in grado di replicare la sintassi della shell consystemd
eseguendo esplicitamente il comando tramite una shell:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
È una funzionalità che consente al sistema di eseguire il codice in un ambiente coerente con i controlli delle risorse. Questo aiuta con risultati riproducibili e stabili a lungo termine senza sovraccaricare l'hardware.
Correlati:cosa indica questo processo STAT?