web-dev-qa-db-fra.com

Scripts de déconnexion: non terminés à l’arrêt, redémarrez

J'essaie de faire certaines choses à la déconnexion et la tâche peut prendre jusqu'à 5 minutes.

Si l'utilisateur choisit directement Power off ou Reboot, le script est tué avant la fin. Si l'utilisateur ne fait que choisir Log out, le script est exécuté sans problème.

J'ai essayé d'utiliser pam_exec et lightdm propriété session-cleanup-script pour désigner mon script, mais c'est la même chose dans les deux cas.

Le script utilisé pour faire les tests est celui-ci:

#!/bin/bash
touch /tmpfile
for p in $(seq 0 300) ; do
    sleep 1
    echo $p >> /tmpfile
done

Lors de la déconnexion, tous les 300 numéros sont écrits dans le fichier. Lorsque vous arrêtez ou redémarrez directement à partir de la session utilisateur, seuls 2 ou 3 chiffres sont écrits, le script est donc supprimé.

Comment est géré l'arrêt par lightdm? Comment puis-je m'assurer que mon script n'est pas en train d'être tué?

Si vous proposez une autre approche, veuillez vous assurer que j'ai besoin de savoir quel utilisateur est déconnecté et de pouvoir exécuter un script en tant qu'utilisateur. Je dois également informer l'utilisateur de ce qui se passe, il est donc préférable de rester sur X si possible.

5

Pour gérer cela, j'ai combiné trois mécanismes:

  • Un script de déconnexion Lightdm, qui récupère les informations utilisateur et les écrit sur un fichier temporaire, afin de savoir qui met l'ordinateur hors tension. Il fait également la lourde tâche dans le cas où nous ne sommes pas en train de fermer ou de redémarrer.
  • Scripts initrd traditionnels pour effectuer les tâches lourdes lors de l'arrêt ou du redémarrage.
  • Messages d’état de Plymouth pour donner des informations sur ces tâches lourdes lors de l’arrêt ou du redémarrage.

Donc, j'ai le script de tâche lourde sur /usr/local/bin/heavy.sh:

#!/bin/bash 
touch /tmpfile 
for p in $(seq 0 300) ; do
    sleep 1
    echo $p >> /tmpfile
    if [ ! -z $DISPLAY ] ; then
        notify-send "Written $p"
    else 
        plymouth message --text="Written $p" &>/dev/null
    fi
done

Cette lourde tâche tente de transmettre des informations à X. Si cela échoue, essayez de le faire à Plymouth.

Ensuite, j'ai ajouté cette ligne à la configuration Lightdm sur /etc/lightdm/lightdm.conf:

session-cleanup-script=/usr/local/sbin/logout-tasks.sh

Le script référencé écrit l'utilisateur lors de la déconnexion et tente d'effectuer la tâche lourde:

#!/bin/bash
echo $USER > /run/last-logout-user
/usr/local/bin/heavy.sh

Le script initrd, situé sur /etc/init.d/logout-heavy-task-at-shutdown:

#!/bin/bash
USER_RUN=$(cat /run/last-logout-user)
Sudo -u $USER_RUN /usr/local/bin/heavy.sh

Cela lance la tâche en tant que dernier utilisateur déconnecté lors de l'arrêt et du redémarrage, en ajoutant les liens correspondants:

 update-rc.d -n logout-heavy-task-at-shutdown start 05 0
 update-rc.d -n logout-heavy-task-at-shutdown start 05 6

Et c'est tout. La tâche lourde devra peut-être être gérée lorsqu'elle sera tuée par X puis relancée par le script initrd. En fonction de la tâche, cela pourrait ne pas être un problème du tout.

0

Dans Ubuntu, les scripts de différents niveaux d’exécution sont exécutés en fonction de leur présence dans les répertoires /etc/rc[0-6].d. Runlevel 0 correspond à l'arrêt et 6 au redémarrage.

Généralement, le script est stocké dans /etc/init.d, puis des liens symboliques sont placés dans les répertoires correspondant aux niveaux d'exécution requis.

Donc, dans votre cas, écrivez votre script, stockez-le dans /etc/init.d/, puis créez un lien symbolique dans chacun de /etc/rc0.d et /etc/rc6.d (si vous voulez les deux) pointant vers votre script.

Créez un lien symbolique comme: /etc/rc0.d/K01myscipt -> /etc/init.d/myscript

Les scripts de chaque répertoire de niveau d'exécution seront exécutés dans l'ordre ASCIIbetical. Si l'ordre dans le niveau d'exécution vous intéresse, choisissez le nom de votre lien symbolique en conséquence.

J'espère que ça résout. N'oubliez pas de le rendre exécutable (Sudo chmod + x myscript). De plus, je ne suis pas sûr, mais vous devrez peut-être annuler l'arrêt au début du script - shutdown -c now et le relancer à la fin - shutdown -h now.

Maintenant, pour savoir qui a émis la commande shutdown:
1) Vous pouvez le faire à l’aide du script suivant:

a. mv /sbin/shutdown /sbin/shutdown-orig
b. vim /sbin/shutdown #!/bin/sh echo "$USER has initiated the shutdown process" >> /var/log/shutdown.owner /sbin/shutdown-orig "$@"
c. chmod 755 /sbin/shutdown

2) Ou bien, un utilisateur normal n'a accès qu'à la commande shutdown via Sudo et Sudo les commandes sont (généralement) consignées sous /var/log/. Donc, vous pouvez vérifier cela. J'espère que ça aide. Pour plus d'informations, veuillez vous référer à mon fil ici . N'oubliez pas de passer et de dire merci à eux.

EDIT: En conclusion, si rien ne fonctionne, essayez d’utiliser Sudo et de bloquer l’accès à l’arrêt/le redémarrage et vous seul pouvez alors vérifier les journaux et savoir qui a lancé le processus d’arrêt. Détail dans le contenu ci-dessous. Merci. Wonderful Question, Learnt a Lot.

2
ASCIIbetical

LightDM

Créez un script dans /etc/rc0.d.

Sudo vim /etc/rc0.d/myScript
Sudo chmod +x /etc/rc0.d/myScript

GDM

Ajoutez votre commande au fichier /etc/gdm/PostSession/Default avant la ligne exit 0.

Comme avant l’arrêt, l’utilisateur est quand même déconnecté, cela devrait couvrir les deux bases.

1
abhshkdz