4 votes

L'option StandardOutput de systemd ne fonctionne pas

Je suis en train d'utiliser systemd pour démarrer un programme au démarrage et le maintenir en fonctionnement en arrière-plan.

J'ai écrit un script simple pour que systemd l'appelle et le script affichera plusieurs lignes de journaux que j'aimerais voir dans le terminal.

J'ai donc défini StandardOutput=journal+console dans la configuration du service mais je n'ai pas pu voir les sorties ni dans le terminal ni dans le journal.

frederick@Frederick-PC:~$ sudo systemctl start my_program.service
frederick@Frederick-PC:~$ journalctl _SYSTEMD_UNIT=my_program.service
Aucun fichier journal trouvé.
-- Aucune entrée --

Et voici la configuration de mon service et le script.

/etc/systemd/system/my_program.service

[Unit]
Description=Démarrer le client my_program après le démarrage du système

[Service]
Type=forking
ExecStart=/usr/bin/my_program.sh start
ExecStop=/usr/bin/my_program.sh stop
PIDFile=/run/my_program.pid
WorkingDirectory=/home/frederick/Applications/my_program-go/
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target

/usr/bin/my_program.sh

#!/bin/sh

start() {
    if [ -f /run/my_program.pid ]; then
        kill -0 $(cat /run/my_program.pid) > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            echo "my_program est déjà démarré"
            exit 1
        fi
    fi
    echo -n "Démarrage de my_program... "
    nohup /home/frederick/Applications/my_program-go/my_program-local -c /home/frederick/Applications/my_program-go/config.json >> /home/frederick/Applications/my_program-go/my_program.log 2>&1 &
    if [ $? -gt 0 ]; then
        echo "échec"
        rm /run/my_program.pid > /dev/null 2>&1
    else
        echo $! | tee /run/my_program.pid
    fi
}

stop() {
    if [ -f /run/my_program.pid ]; then
        echo -n "Arrêt de my_program... "
        msg=$(kill $(cat /run/my_program.pid) 2>&1)
        if [ $? -gt 0 ]; then
            echo "échec"
            echo $msg
        else
            rm /run/my_program.pid > /dev/null 2>&1
            echo "réussi"
        fi
    else
        echo "my_program n'est pas démarré"
    fi
}

restart() {
    stop
    start
}

case $1 in
    start|stop|restart)
        "$1"
        ;;
    *)
        echo "Opération inconnue"
        exit 1
        ;;
esac

Comment puis-je voir ces lignes imprimées par echo dans le script? S'il vous plaît aidez-moi, merci.

7voto

JdeBP Points 25711

J'ai écrit un script simple pour systemd pour appeler …

… qui était la source du problème. Votre "script simple" a annulé là où la sortie standard et l'erreur standard étaient envoyées. Et cela entièrement inutilement. Toute la redirection, l'écriture du fichier PID, l'exécution de nohup, et le fork sont entièrement inutiles pour quelque chose qui est déjà daemonisé et pour lequel le PID est déjà connu par le gestionnaire de service. Vous n'avez pas besoin de cette partie du script du tout. Au lieu de cela, écrivez votre unité de service comme ceci:

\[Unit\]
Description=Démarrer le client de mon\_programme après le démarrage du système

\[Service\]
Type=simple
ExecStart=/home/frederick/Applications/my\_program-go/my\_program-local -c /home/frederick/Applications/my\_program-go/config.json
WorkingDirectory=/home/frederick/Applications/my\_program-go/
StandardOutput=journal+console

\[Install\]
WantedBy=multi-user.target

Utilisez toutes les options nécessaires pour empêcher votre programme de fork, sauf s'il met effectivement en œuvre le protocole de préparation au fork. Très peu de programmes le font effectivement. Votre "script simple" ne l'a certainement pas fait, car il a arrêté le processus parent bien avant que le démon ne soit initialisé et prêt.

Lecture supplémentaire

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X