Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-21 Par sujet Basile Starynkevitch



On 02/20/2018 06:48 PM, Raphaël POITEVIN wrote:

G2PC  writes:


Comment lancer un script shell linux lors de la fermeture du terminal,
avec la croix. ... ?

L’appeler dans .bash_logout ?


Moi j'aimerais comprendre pourquoi on veut faire ça. Je n'en vois pas la 
raison. Un emulateur de terminal peut
disparaître à tout moment (par exemple avec xkill), indépendamment du 
shell (ou du programme) qui y est executé.


Une possibilité (peut-être) serait de choisir puis configurer un window 
manager convenable pour ça.


A mon avis la question initiale est une instance de problème XY 
http://xyproblem.info/ et mériterait une motivation poussée.


Librement

--
Basile STARYNKEVITCH   == http://starynkevitch.net/Basile
opinions are mine only - les opinions sont seulement miennes
Bourg La Reine, France



Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-21 Par sujet Étienne Mollier


On 02/20/2018 06:48 PM, Raphaël POITEVIN wrote:
> G2PC  writes:
> 
>> Comment lancer un script shell linux lors de la fermeture du terminal,
>> avec la croix. ... ?
> 
> L’appeler dans .bash_logout ?
> 

Bonsoir,

L'approche est intéressante, mais ne marcherait pas dans le cas
concernant les terminaux quittés via la croix pour deux raisons.
La première est que la plupart des terminaux ne lancent pas par
défaut des shells de login, et la seconde est que, dans le cas
d'une utilisation dans un script de login, le .bash_logout n'est
appelé qu'a l'appel de la commande « exit ».

Ceci dit, c'était bien pensé.  :-)

La section « INVOCATION » du manuel de Bash est assez détaillée
à ce sujet :

   When an interactive login shell exits, or a non-interac‐
   tive login shell executes the exit builtin command, bash
   readsandexecutescommands   from   the   file
   ~/.bash_logout, if it exists.


Il est toujours intéressant de noter que les terminaux des
divers environnements de bureau peuvent être configurés pour
être des shells de login via une option à cocher dans les
préférences.  Pour le terminal XTerm, vous pouvez le lancer avec
l'option -ls.

La morale de cette histoire est que, c'est mal de fermer ses
terminaux avec la croix : si un programme en cours d'exécution
avait eu besoin de faire du ménage, il y a de grandes chances
pour qu'il faille repasser derrière faire le ménage à la mimine.
Gérer ce cas proprement au sein des programmes n'est pas simple.

À plus,
-- 
Étienne Mollier 



Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-20 Par sujet Raphaël POITEVIN
G2PC  writes:

> Comment lancer un script shell linux lors de la fermeture du terminal,
> avec la croix. ... ?

L’appeler dans .bash_logout ?
-- 
Raphaël



Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-18 Par sujet G2PC
Le 18/02/2018 à 21:19, Étienne Mollier a écrit :
> G2PC, le 2018-02-18 :
>> Oui, si je lance le script, un fichier est créé, contenant la
>> date.  Non, le fichier n'est pas créé lorsque je quitte le
>> terminal avec la croix. J'ai tenté de le fermer au bout d'une
>> minute, mais, la date est ajoutée dans le fichier texte au
>> lancement du script, pas à la fermeture de la fenêtre.
> De ce que vous décrivez, la fonction rattachée à l'évènement
> s'exécuterait donc dès la déclaration de la fonction ; il y a
> peut-être un bug dans votre essai.
>
> Voici un script qui m'a permis de faire des tests plus poussés
> pour simuler un installateur classique :
>
>   #!/bin/bash
>   set -e
>   set -v
>   
>   # Creating an installation directory with a unique name,
>   # to avoid concurrency issues.
>   INSTALLDIR="$(mktemp -d installdir.XX)"
>   
>   # Setting up cleanup of the installation directory on
>   # exit.  WARNING: do not use `cd` in the script, as
>   # INSTALLDIR is a relative path.
>   clean-installdir () {
>   rm -r "$INSTALLDIR"
>   }
>   trap clean-installdir EXIT
>   
>   # Installing...
>   printf "Installation in progress in %s\n" "$INSTALLDIR"
>   # The sleeping simulates the time it would take for a
>   # real installation to occur.  You can close the program
>   # in any way you wish, to do some tests, in this time
>   # frame.
>   sleep 10
>   
>   # Everything went well for the script
>   printf "%s\n" "Done."
>   
>   # Note that you should see execution of clean-installdir
>   # here, as the program is exiting.  :-)
>
> Si je ferme le programme à coup de , ou si je clos la
> fenêtre avec le raccourci clavier de mon gestionnaire de fenêtre,
> le répertoire d'installation est effacé.  Si je laisse le
> programme s'exécuter jusqu'au bout, c'est aussi le cas /sans/
> appeler explicitement la fonction ; ce qui, soit dit en passant,
> est cool.
>
> Si je ferme la fenêtre de mon terminal avec le programme xkill,
> le script reçoit un signal KILL impossible à capter.  Par
> conséquent, le répertoire d'installation reste présent à côté du
> script, et doit être effacé manuellement.  Il se peut que
> certains gestionnaires de fenêtres aient ce genre de comportement
> pour lutter contre les fenêtres récalcitrantes.  Je n'ai testé
> que dwm de mon côté, mais il y en a d'autres : xfwm4, metacity,
> kwin, awesome, fvwm, openbox, et j'en passe.
>
>
>> Si le script ne fini pas normalement, ce n'est pas trop grâve,
>> un dossier installeur restera présent dans le répertoire
>> utilisateur.  J'ai pu lire d'avantage, sur mktemp :
>> https://www.visionduweb.eu/wiki/index.php?title=Programmation_en_Shell_Bash_Linux#Cr.C3.A9er_un_fichier_temporaire_avec_mktemp
>> C'est une solution intéressante !
>>
>> Malgré tout, ma question reste posée, avec un exemple, si il est
>> possible de lancer un script au moment de la fermeture d'un
>> terminal, avec la croix.
>> C'est surement inutile, puisque d'autres possibilités comme
>> mktemp sont adaptées.
> Gardez la commande mktemp en tête, elle ne remplace pas le mécano
> avec trap, mais elle participe à régler les problèmes de
> concurrence mentionnés dans mon précédent courriel.
>
>
> À plus,

Ici, effectivement, le fichier va être nettoyé automatiquement à la fin
de l'installation, ou, immédiatement, quand je ferme le terminal avec la
croix.
C'est tout à fait ce que j'attendais comme retour, et, oui, ça
fonctionne plutôt bien.

Noter que, il faut bien lancer le script en bash, avec sh, ça ne
fonctionnera pas.

Je note également que certains tueurs de programmes pourront empêcher le
bon fonctionnement du script, si trap n'est pas appelé normalement.

Bonne soirée, bonne fin de week end.
Merci beaucoup pour l'exemple.




Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-18 Par sujet Étienne Mollier
G2PC, le 2018-02-18 :
> Oui, si je lance le script, un fichier est créé, contenant la
> date.  Non, le fichier n'est pas créé lorsque je quitte le
> terminal avec la croix. J'ai tenté de le fermer au bout d'une
> minute, mais, la date est ajoutée dans le fichier texte au
> lancement du script, pas à la fermeture de la fenêtre.

De ce que vous décrivez, la fonction rattachée à l'évènement
s'exécuterait donc dès la déclaration de la fonction ; il y a
peut-être un bug dans votre essai.

Voici un script qui m'a permis de faire des tests plus poussés
pour simuler un installateur classique :

#!/bin/bash
set -e
set -v

# Creating an installation directory with a unique name,
# to avoid concurrency issues.
INSTALLDIR="$(mktemp -d installdir.XX)"

# Setting up cleanup of the installation directory on
# exit.  WARNING: do not use `cd` in the script, as
# INSTALLDIR is a relative path.
clean-installdir () {
rm -r "$INSTALLDIR"
}
trap clean-installdir EXIT

# Installing...
printf "Installation in progress in %s\n" "$INSTALLDIR"
# The sleeping simulates the time it would take for a
# real installation to occur.  You can close the program
# in any way you wish, to do some tests, in this time
# frame.
sleep 10

# Everything went well for the script
printf "%s\n" "Done."

# Note that you should see execution of clean-installdir
# here, as the program is exiting.  :-)

Si je ferme le programme à coup de , ou si je clos la
fenêtre avec le raccourci clavier de mon gestionnaire de fenêtre,
le répertoire d'installation est effacé.  Si je laisse le
programme s'exécuter jusqu'au bout, c'est aussi le cas /sans/
appeler explicitement la fonction ; ce qui, soit dit en passant,
est cool.

Si je ferme la fenêtre de mon terminal avec le programme xkill,
le script reçoit un signal KILL impossible à capter.  Par
conséquent, le répertoire d'installation reste présent à côté du
script, et doit être effacé manuellement.  Il se peut que
certains gestionnaires de fenêtres aient ce genre de comportement
pour lutter contre les fenêtres récalcitrantes.  Je n'ai testé
que dwm de mon côté, mais il y en a d'autres : xfwm4, metacity,
kwin, awesome, fvwm, openbox, et j'en passe.


> Si le script ne fini pas normalement, ce n'est pas trop grâve,
> un dossier installeur restera présent dans le répertoire
> utilisateur.  J'ai pu lire d'avantage, sur mktemp :
> https://www.visionduweb.eu/wiki/index.php?title=Programmation_en_Shell_Bash_Linux#Cr.C3.A9er_un_fichier_temporaire_avec_mktemp
> C'est une solution intéressante !
>
> Malgré tout, ma question reste posée, avec un exemple, si il est
> possible de lancer un script au moment de la fermeture d'un
> terminal, avec la croix.
> C'est surement inutile, puisque d'autres possibilités comme
> mktemp sont adaptées.

Gardez la commande mktemp en tête, elle ne remplace pas le mécano
avec trap, mais elle participe à régler les problèmes de
concurrence mentionnés dans mon précédent courriel.


À plus,
-- 
Étienne Mollier 



Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-18 Par sujet G2PC
Le 18/02/2018 à 19:31, Étienne Mollier a écrit :
> last-exit () {
>   printf '%s\n' "$(date --rfc-2822)" > ~/.lastexit
>   }
>   trap last-exit EXIT

Bonsoir, et, merci pour le retour.
J'ai testé sur ma VM, mais, sans succès.

Oui, si je lance le script, un fichier est créé, contenant la date.
Non, le fichier n'est pas créé lorsque je quitte le terminal avec la
croix. J'ai tenté de le fermer au bout d'une minute, mais, la date est
ajoutée dans le fichier texte au lancement du script, pas à la fermeture
de la fenêtre.

Si le script ne fini pas normalement, ce n'est pas trop grâve, un
dossier installeur restera présent dans le répertoire utilisateur.
J'ai pu lire d'avantage, sur mktemp :
https://www.visionduweb.eu/wiki/index.php?title=Programmation_en_Shell_Bash_Linux#Cr.C3.A9er_un_fichier_temporaire_avec_mktemp
C'est une solution intéressante !

Malgré tout, ma question reste posée, avec un exemple, si il est
possible de lancer un script au moment de la fermeture d'un terminal,
avec la croix.
C'est surement inutile, puisque d'autres possibilités comme mktemp sont
adaptées.



Re: Lancer un script shell linux lors de la fermeture du terminal, avec la croix

2018-02-18 Par sujet Étienne Mollier
Bonjour,


> Comment lancer un script shell linux lors de la fermeture du
> terminal, avec la croix. ... ?

On peut potentiellement déjà avoir des problèmes dépendant de la
façon dont le gestionnaire de fenêtre utilisé ferme les fenêtres
avec la croix, s'il y a une croix...  :-)

Normalement, tous le font de manières à laisser le temps à
l'application d'exécuter des tâches de nettoyage avant de
quitter, mais on peut avoir des surprises, en particulier si un
signal SIGKILL, qui ne peut de toute façon pas être trap'é, est
lancé trop tôt...


> J'ai vu sur un forum qu'il serrait question d'utiliser SIGHUP.
>
> Je n'ai pas réussi à reproduire l'exemple proposé. ( appel de
> fonction "a" qui écrit correctement dans un fichier de logs ,
> trap "a" )

Effectivement d'après le manuel signal(7) ça aurait pu avoir du
sens :

   Signal Value Action   Comment
   ──
   SIGHUP1   TermHangup detected on controlling terminal
 or death of controlling process

Mais à l'usage, ça ne passe pas.  Il me semble que ce signal est
plutôt utilisé pour recharger la configuration des dæmons sans
avoir à les redémarrer, ou ce genre de chose, désormais.

Il pourrait néanmoins y avoir une solution.  Si le shell utilisé
est bash, alors il est possible de spécifier un pseudo signal
EXIT à la commande trap (pas SIGEXIT, ce n'est pas un signal
inter processus à proprement parler).  Le code suivant permet par
exemple d'enregistrer la dernière fermeture de shell (testé avec
le gestionnaire dwm en faisant l'équivalent d'un clic sur une
hypothétique croix) :

last-exit () {
printf '%s\n' "$(date --rfc-2822)" > ~/.lastexit
}
trap last-exit EXIT

L'explication détaillée à propos de EXIT (et de quelque signaux
bonus) est disponible dans le manuel de bash, ou bien en sortie
de la commande :

$ help trap
trap: trap [-lp] [[arg] signal_spec ...]
Trap signals and other events.

Defines and activates handlers to be run when the shell receives 
signals
or other conditions.
[...]
If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the 
shell.  If
[...]


Ça marche avec le bash de Debian Sid, je n'ai pas testé avec les
autres niveaux de Debian, donc je ne saurais dire si c'est une
solution éprouvée ou bien si c'est une nouveauté.  :-)


Une autre solution exploitant le fichier ~/.bash_logout aurait pu
être envisagée mais suppose que la fenêtre de terminal a été
lancée avec `bash -l` et non `bash` tout court, qui est une
commande par défaut usuelle.  De plus, le nettoyage
s'appliquerait à toute session utilisateur, et pas seulement dans
le contexte de votre script.


> J'aimerais pouvoir déclancher la suppression d'un dossier, si
> l'utilisateur de quitte pas mon script avec la commande EXIT du
> menu que j'ai créé.

Juste pour éviter les cafouillages, le EXIT que je mentionne est
une entité différente du EXIT de votre menu.

Soyez prudents avec les situations de concurrence également.
Qu'est ce qui se passe quand un terminal dans un autre contexte
est fermé avec la croix ? Est ce que ça va déclencher le script
de nettoyage ?  Est ce bienvenu ?  Et si le programme tourne dans
d'autres terminaux, comment se comporte le nettoyage ?...


À plus,
-- 
Étienne Mollier