Je suis curieux de savoir quelle est cette différence entre les programmes qui sont; démarré avec systemd lorsqu'il est activé via systemctl, par rapport à ceux démarrés au moyen de /etc/rc.local
ou via la CLI.
Par exemple, j'utilisais récemment shairport-sync pour le raspberry pi. Initialement, j'ai configuré shairport-sync pour qu'il démarre au moyen de sudo systemctl activé shairport-sync.
Plus tard, j'ai utilisé une fonctionnalité dans shairport-sync
pour exécuter des scripts avant et publier sur les appareils connectés.
À ma grande surprise, les scripts lorsqu'ils sont exécutés par shairport-sync
n'a pas kill
arecord
ou aplay
Cependant, lorsque j'exécutais le script via le terminal, le script s'exécutait et tuait arecord
et aplay
.
Pour me confondre davantage, j'ai tué shairport-sync
et l'a démarré via le terminal pour voir la sortie de ce qui se passait. Lorsque je l'ai fait, les scripts ont fonctionné comme prévu lorsque l'appareil s'est connecté et a tué arecord
et aplay
. Donc, comme solution, j'ai désactivé shairport-sync
dans sysmtectl
et configurez-le pour qu'il s'exécute dans /etc/rc.local
comme une solution rapide. Après un reboot
il a fonctionné comme je m'y attendais.
Cela me porte à croire qu'il existe une différence entre un programme exécuté en dehors de systemd
et un programme qui s'exécute au démarrage via /etc/rc.local
ou la CLI.
Pourquoi cela arrive-t-il? Est-ce à cause des différents niveaux d'exécution ? Un peu de magie noire ?
Le script exécuté lorsqu'un appareil se connecte à shairport-sync
est le suivant :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
Voici le script de fondu :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
Le script exécuté lorsqu'un appareil se déconnecte de shairport-sync
est le suivant :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
J'ai trouvé l'erreur suivante dans le /var/log/syslog
uniquement lorsque shairport-sync a été initialement exécuté en dehors de systemd
. Lorsque shairport-sync
a été exécuté depuis la CLI ou /etc/rc.local
il n'y avait pas d'erreurs présentes.
Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
Veuillez noter que la seule différence est la façon dont shairport-sync
est initialement démarré, lorsque les appareils se connectent ou se déconnectent shairport-sync
continue de fonctionner.
Réponse acceptée :
Variations de "Pourquoi les choses se comportent-elles différemment sous systemd ?" sont une question fréquemment posée.
Chaque fois que quelque chose s'exécute à partir de la CLI et non de systemd, il existe de grandes catégories de possibilités pour tenir compte des différences.
- Différentes variables d'environnement .
systemd
documente les variables d'environnement qu'il passe dansman systemd.exec
dans la section Variables d'environnement dans les processus engendrés. Si vous voulez inspecter la différence vous-même, vous pouvez utilisersystemd-run /path/to/binary
, il exécutera votre application dans une portée transitoire, car elle serait exécutée par un service systemd. Vous obtiendrez une sortie comme :Running as unit: run-u160.service
. Vous pouvez alorsjournalctl -u run-u160.service
pour revoir la sortie. Modifiez votre application pour vider les variables d'environnement qu'elle reçoit et comparez l'exécution de la CLI à l'exécution de systemd. Si l'application n'est pas facilement modifiée, vous pouvez simplement utilisersystemd-run env
pour voir les variables d'environnement qui seraient transmises et passer en revue la journalisation du journal qui en résulte. Si vous essayez de démarrer une application graphique X11, leDISPLAY
La variable d'environnement doit être définie. Dans ce cas, envisagez d'utiliser la fonctionnalité "démarrage automatique" de votre environnement de bureau au lieu desystemd
. - Restrictions de ressources . Voir
man systemd.resource-control
pour les valeurs de configuration qui pourraient limiter la consommation de ressources. Utilisezsystemctl show your-unit-unit.service
pour vérifier les valeurs de configuration complètes affectant le service que vous tentez de démarrer. - Shell non interactif . Votre
bash
L'environnement CLI est un shell de connexion interactif . Il a des fichiers source comme.bashrc
quesystemd
n'a pas. En plus de définir des variables d'environnement, ces scripts peuvent faire un certain nombre d'autres choses, comme connecter un agent SSH afin que les actions SSH ne nécessitent pas de connexion. Voir aussi Différence entre le shell de connexion et le shell sans connexion ? - Pas d'ATS . Votre session interactive est connectée à un TTY que certains programmes comme
sudo
etssh
attendre lors de la demande de mots de passe. Voir aussi sudo :aucun tty présent et aucun programme askpass spécifié - Chemins relatifs et chemins absolus . Travail binaire relatif dans le shell, mais comme documenté dans
man systemd.service
, le premier argument deExecStart=
doit être un chemin absolu vers un binaire. - Syntaxe de ligne de commande restreinte . Les CLI Shell prennent en charge de nombreux métacaractères, tandis que
systemd
a une syntaxe de ligne de commande très restreinte. Selon vos besoins, vous pourrez peut-être répliquer la syntaxe Shell avecsystemd
en exécutant explicitement votre commande via un shell :ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
C'est une fonctionnalité que le système exécute votre code dans un environnement cohérent avec des contrôles de ressources. Cela permet d'obtenir des résultats reproductibles et stables à long terme sans surcharger le matériel.
En relation :Qu'est-ce que ce processus STAT indique ?