web-dev-qa-db-fra.com

Intercepter un appel d'arrêt et exécuter un script pour autoriser ou empêcher l'arrêt

En ce moment, mon ordinateur portable commence à avoir ce que je pense, des problèmes matériels. Parfois, je dois essayer 3 fois avant que cela commence avec succès. J'essaie de sauvegarder le code que je modifie dans ma clé USB mais parfois, j'oublie. C'est pourquoi je me demande s'il existe un moyen d'exécuter un script lorsque l'utilisateur souhaite éteindre l'ordinateur. Ce script vérifiera plusieurs choses et selon la situation, il annulera l’arrêt et demandera à l’utilisateur d’effectuer une action (insérer une clé usb par exemple), ou d’exécuter certaines instructions (enregistrer au format usb) et autoriser le arrêt après. En raison de cette interaction nécessaire avec l'utilisateur, le simple fait de placer le script sous /etc/rc0.d ne suffira pas.

Merci

2
Karim Mtl

Utiliser des inhibiteurs systémiques

Message original se trouve dans la section ci-dessous et explique comment intercepter la commande /sbin/shutdown. Cette section est basée sur inhibiteurs de systemd .

De inhibiteur de système :

Nom

systemd-inhibit - Exécute un programme avec un blocage d'inhibition pris

Synopsis

systemd-inhibit [OPTIONS...] [COMMAND] [ARGUMENTS...]

systemd-inhibit [OPTIONS...] --list

La description

systemd-inhibit peut être utilisé pour exécuter un programme avec un verrouillage d'arrêt, de veille ou d'inhibition inactif. Le verrou sera acquis avant l'exécution de la ligne de commande spécifiée, puis libéré.

Les verrouillages d'inhibiteurs peuvent être utilisés pour bloquer ou retarder les demandes de mise en veille et d'arrêt du système, ainsi que le traitement automatique en mode veille du système d'exploitation. Ceci est utile pour éviter que le système suspende pendant l'enregistrement d'un disque optique ou pour des opérations similaires qui ne doivent pas être interrompues.

Pour plus d'informations, voir Documentation du développeur sur le verrouillage d'inhibiteur .

Les options

Les options suivantes sont comprises:

--what=

  • Prend une liste d'une ou plusieurs opérations séparées par deux points pour empêcher: "shutdown", "sleep", "inactif", "handle-power-key", "handle-suspend-key", "handle-hibernate-key", "handle-lid-switch", pour empêcher le redémarrage/extinction/arrêt/kexec, la suspension/l'hibernation, la détection automatique du ralenti ou la manipulation à bas niveau de la touche d'alimentation/veille et de l'interrupteur de couvercle, respectivement. Si omis, "par défaut: sommeil: arrêt" par défaut.

--who=

  • Prend une chaîne descriptive courte, lisible par l'homme, pour le programme verrouillé. S'il n'est pas transmis, la chaîne de ligne de commande est utilisée par défaut.

--why=

  • Prend une chaîne descriptive courte, lisible par l'homme, pour indiquer le motif du verrouillage. La valeur par défaut est "Motif inconnu".

--mode=

  • Prend "block" ou "delay" et décrit comment le verrou est appliqué. Si "block" est utilisé (valeur par défaut), le verrou interdit toute opération demandée sans limite de temps et seuls les utilisateurs privilégiés peuvent la remplacer. Si "délai" est utilisé, le verrou ne peut retarder les opérations demandées que pendant un temps limité. Si le temps est écoulé, le verrou est ignoré et l'opération exécutée. La limite de temps peut être spécifiée dans logind.conf (5) . Notez que "délai" est uniquement disponible pour "veille" et "arrêt".

--list

  • Répertorie tous les verrous d'inhibition actifs au lieu d'en acquérir un.

-h, --help

  • Imprimez un court texte d'aide et quittez.

--version

  • Imprimez une version courte de la chaîne et quittez.

Statut de sortie

Retourne le statut de sortie du programme exécuté.

Exemple

# systemd-inhibit wodim foobar.iso

Ceci grave l’image ISO foobar.iso sur un CD en utilisant wodim (1) . Remarque: le lien est rompu dans la documentation de systemd et empêche la mise en veille, l’arrêt et la veille du système.

Voir également

systemd (1) , logind.conf (5)


Poste originale

En concept, cela semble assez facile. Recherchez simplement la commande, renommez-la et remplacez-la par votre propre script qui appelle la version renommée:

$ type -a shutdown
shutdown is /sbin/shutdown
$ Sudo mv /sbin/shutdown /sbin/shutdownoriginal

Ensuite, éditez votre propre script dans /sbin/shutdown contenant au minimum:

#!/bin/bash
/sbin/shutdownoriginal

Marquez ensuite votre script comme exécutable pour tout le monde:

$ Sudo chmod a+x /sbin/shutdown

Voila! Tout ce qui appelle shutdown appelle maintenant votre script qui appelle ensuite la commande originale.

En réalité, au moment où votre script est appelé, les choses peuvent ne pas être dans l'état que vous attendez. Par exemple, je mets quelques commandes pour enregistrer l'arrêt mais elles ne semblent pas fonctionner:

echo "/sbin/shutdown custom script calling /sbin/shutdownoriginal"
shutdowntime=`date`
echo "Last shutdown: $shutdowntime" >> /home/rick/shutdownlog.txt

Le premier echo aurait dû apparaître dans /var/log/syslog mais ce n’était pas le cas. Le second echo aurait dû ajouter une ligne au fichier journal, mais ce n’était pas le cas. Cela me dit que lorsque la commande /sbin/shutdown est exécutée, la journalisation système est déjà désactivée et le système d'E/S sur fichier est arrêté.

Une meilleure approche consisterait à examiner les inhibiteurs d’entrée et de cible d’arrêt de systemd. Je laisserai cette réponse ici, mais pour les autres qui pourraient penser que cela pourrait/devrait/devrait fonctionner.

Comme toujours, rappelez-vous YMMV - Y notre M ileage M ay V ery.

2
WinEunuuchs2Unix

J'ai regardé systemd-inhibit

Ce que j'ai compris, c'est que lorsque vous l'utilisez avant une commande, elle attend que votre commande/script se termine avant que le système ne s'éteigne. Il existe quelques options pour bloquer l'arrêt, mais cela ne m'a pas semblé évident de le faire. Pour le moment, votre première suggestion fonctionne pour moi (cela ne me dérange pas de taper "shutdown" à la place de l'interface graphique). Voici un script de base à titre d'exemple:

#!/bin/bash

if [ ! -d /media/myusername/myusbname ]; then
  zenity --question --text "Are you sure you want to shutdown without saving? If not choose \"No\" and insert the usb key" 2> /dev/null
  answer=$?
else
  #save data
  answer=0
fi
if [ $answer -eq 0 ]; then
  /sbin/shutdownoriginal
else
  zenity --info --text="Shutdown canceled" 2> /dev/null
fi

Je vous remercie

0
Karim Mtl