Differenza tra systemd e programma di avvio terminale


9

Sono curioso di sapere quale sia questa differenza tra i programmi; iniziato con systemd quando abilitato tramite systemctl, rispetto a quelli avviati tramite /etc/rc.localo tramite l' interfaccia della riga di comando .

Ad esempio, recentemente stavo usando shairport-sync per il raspberry pi. Inizialmente, ho impostato shairport-sync per iniziare tramite shadoport-sync abilitato sudo systemctl.

Più tardi lungo la strada ho usato una funzionalità all'interno shairport-syncper eseguire script prima e inviare ai dispositivi di connessione.

Con mia sorpresa, gli script eseguiti da shairport-syncnon lo hanno fatto kill arecordoaplay

Tuttavia, quando eseguivo lo script tramite terminale, lo script veniva eseguito, ucciso arecorde aplay.

Per confondermi ulteriormente, l'ho ucciso shairport-synce 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 è collegato, ucciso arecorde aplay. Così, come una correzione ho disabilitato shairport-syncin sysmtectle impostarlo per l'esecuzione in /etc/rc.localcome una soluzione rapida. Dopo rebootche ha funzionato come mi aspettavo.

Questo mi porta a credere che ci sia qualche differenza tra un programma eseguito a parte systemde un programma che viene eseguito quando avviato tramite /etc/rc.localo l'interfaccia della riga di comando.

Perché succede? È a causa di diversi livelli di esecuzione? Qualche magia oscura?

Lo script che viene eseguito quando un dispositivo si connette 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 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 nel /var/log/syslogsolo quando shairport-sync è stato inizialmente eseguito separatamente systemd. Quando è shairport-syncstato eseguito dalla CLI o /etc/rc.localnon erano presenti errori.

Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified

Si noti che l'unica differenza è come shairport-syncviene avviato inizialmente, quando i dispositivi si connettono o si disconnettono shairport-synccontinuano a funzionare.


1
Quella ps ... awk ... grep ...roba potrebbe essere sostituita da una più semplicepkill
thrig

@thrig originariamente la linea era molto più semplice, ma dal momento che non funzionava o così pensavo di aver provato ad usare altri metodi per uccidere l'istanza che ancora non funzionava. Uccidere il processo non era di per sé il problema, poiché funzionava, ma solo quando eseguito da un login utente
Brett Reinhard,

puoi mostrare la lista di /home/pi/shScripts/shairportfade.sh?
Michael D.

@MichaelD. ho aggiunto lo script di dissolvenza e lo script che viene eseguito quando un dispositivo si disconnette per shairport-sync
Brett Reinhard

@BrettReinhard qual è il problema con l'esecuzione dello scriptrc.local
Michael D.

Risposte:


18

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.

  1. Diverse variabili d'ambiente . systemddocumenta le variabili d'ambiente che passa nella man systemd.execsezione Variabili d'ambiente nei processi generati . Se vuoi controllare tu stesso la differenza, puoi usarla systemd-run /path/to/binary, eseguirà la tua app in un ambito transitorio, come sarebbe gestita da un servizio systemd. Otterrete output come: Running as unit: run-u160.service. È quindi possibile journalctl -u run-u160.servicerivedere l'output. Modifica l'app per eseguire il dump delle variabili di ambiente che riceve e confronta l'esecuzione della CLI con l'esecuzione di systemd. Se l'app non viene opportunamente modificata, puoi semplicemente utilizzare systemd-run envper visualizzare le variabili di ambiente che verrebbero passate e rivedere la registrazione del diario risultante per essa. Se si sta tentando di avviare un'app GUI X11, è necessario impostare la DISPLAYvariabile di ambiente. In tal caso, è consigliabile utilizzare la funzione "avvio automatico" dell'ambiente desktop anziché systemd.
  2. Restrizioni alle risorse . Vedere i man systemd.resource-controlvalori di configurazione che potrebbero limitare il consumo di risorse. Utilizzare systemctl show your-unit-unit.serviceper verificare i valori di configurazione completi che influiscono sul servizio che si sta tentando di avviare.
  3. Shell non interattiva . Il tuo bashambiente CLI è una shell di accesso interattiva . Ha file di origine come .bashrcquello systemdno. Oltre all'impostazione delle variabili di ambiente, questi script possono eseguire qualsiasi altra operazione, ad esempio 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?
  4. Nessun TTY . La tua sessione interattiva è connessa a un TTY che alcuni programmi gradiscono sudoe si sshaspettano quando richiedono password. Vedi anche sudo: nessun programma presente e nessun programma askpass specificato
  5. Percorsi relativi e assoluti . Lavoro binario relativo nella shell, ma come documentato inman systemd.service , il primo argomento ExecStart=deve essere un percorso assoluto di un binario.
  6. Sintassi della riga di comando limitata . Le CLI della shell supportano molti metacaratteri, mentre systemdhanno una sintassi della riga di comando molto limitata . A seconda delle esigenze, potresti essere in grado di replicare la sintassi di Shell systemdeseguendo esplicitamente il tuo comando attraverso una shell:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'

È una funzionalità che il sistema esegue il codice in un ambiente coerente con i controlli delle risorse. Ciò consente risultati riproducibili e stabili a lungo termine senza sovraccaricare l'hardware.


Inoltre, è necessario tenere conto del contesto MAC (SELinux, ...), delle capacità, degli spazi dei nomi ...
Bigon,

2
@BrettReinhard Non richiamare sudomeglio uno script di shell sudo shairportstart.shdal terminale, poiché systemd esegue lo script come root, non è necessario eseguirne il sudo come root.
Michael D.

1
Ho risolto il mio problema in diversi modi nel mio tentativo di capire cosa stava succedendo. Alla fine, quello che ho finito è stato cambiare il mio comando kill /usr/bin/echo "mypassword" | /usr/bin/sudo /bin/pkill arecord. Più tardi oggi, proverò a rimuovere i comandi sudoe echoal mio comando kill e vedrò se questo produce gli stessi risultati. La mia ipotesi è che funzionerà, in quanto sembra che l'errore sia stato causato da nessuna password inviata con il sudocomando. Grazie per l'aiuto nella comprensione del perché c'è una differenza tra systemde la CLI
Brett Reinhard

1
Un'altra differenza, che può essere ovvia ma che mi ha morso oggi, è che systemd tenta di tracciare lo stato di un servizio e non lo avvierà se pensa che sia già attivo, quindi potrebbe anche non avviare uno script init.d se pensa che il servizio sia in esecuzione. Al contrario, gli script init.d vengono in genere scritti per verificare e provare sempre ad avviare il servizio nel modo appropriato.
Josh Kelley,

1
@JoshKelley Grazie per la punta. Questa non è una differenza tra systemd e l'interfaccia della riga di comando, ma tra gli script init.d di systemd e sysVinit.
Mark Stosberg,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.