Syntax corrections and rewords

This commit is contained in:
Yorick Barbanneau 2022-11-15 17:23:20 +01:00
parent 9e3e4729ab
commit ba9ce8fec9

View file

@ -1,6 +1,6 @@
Title: Bash avancé: les pièges (à signaux)
Title: Bash avancé: It's a trap!
Category: sysadmin
Tags: bash, script, pl-fr
Tags: bash, script, signaux, pl-fr
Date: 2022-11-15 8:30
Cover: assets/backgrounds/ackbar-trap.jpg
@ -9,8 +9,8 @@ article de blog. Le seul et unique article de cette année parlait de *Bash* qui
a eu un peu de succès. Comme toute les séries B un peu populaire, il lui fallait
une suite. Et bien la voici!
Dans cette suite, il va être question de faire un peu le ménage lorsque votre
script s'arrête, que se soit gracieusement ou pas, mais pas que...
Dans cette suite, il va être question de signaux, de **"trap"** et bien entendu
de Bash.
## Dis, c'est quoi un signal
@ -20,13 +20,13 @@ réponds pas dans votre terminal et que vous faites Ctrl+C, le système envoi le
signal SIGINT au processus en cours lui signifiant d'interrompre séance tenante
toute action. Chaque signal est associé à un numéro
Voici un liste de quelques signaux (norme POSIX):
Voici un liste de quelques signaux (norme POSIX) :
Signal | Valeur | Action | Commentaire
--------|--------|--------|----------------------------------------------------
SIGHUP | 1 | Term | Déconnexion du terminal ou fin du processus de contrôle
SIGINT | 2 | Term | Interruption depuis le clavier `CTRL + C`
SIGQUIT | 3 | Core | Demande ”Quitter” depuis le clavier `CTRL + \\`
SIGQUIT | 3 | Core | Demande ”Quitter” depuis le clavier `CTRL + \`
SIGILL | 4 | Core | Instruction illégale
SIGABRT | 6 | Core | Signal darrêt depuis abort(3)
SIGFPE | 8 | Core | Erreur mathématique virgule flottante
@ -55,7 +55,7 @@ ré-identifier).
Si le script ne se passe pas comme prévu alors il est plutôt conseillé de faire
le ménage et terminer la connexion maitre.
```bash
```bash
#!/usr/bin/env bash
# Changer ces valeurs par celles adapté à votre configuration
@ -114,9 +114,6 @@ do
done
```
Ce script se lance sans paramètre ou avec le paramètre error afin de générer une
erreur. Étudions le un peu.
La connexion principale est intiée par la fonction `connect`. Juste en dessous
de l'appel de cette dernière nous trouvons notre instruction `trap`. Elle
appelle la commande `cleanup` lorsque le signal `EXIT` est envoyé.
@ -136,9 +133,9 @@ Nous avons donc de quoi tester trois scénarios
### Laisser le script finir normalement
Appeler le script sans argument et le laisser se terminer sans intervenir est
notre premier scénario. Voici le résultat:
notre premier scénario. Voici le résultat :
```shell
```none
$ ./script.sh
Create SSH main connection wih socket /tmp/TvCuLSzkMN
Enter passphrase for key '/home/user/.ssh/key.ed25519':
@ -155,9 +152,9 @@ notre script exécutée par le signal `EXIT`
### Générer une erreur
Maintenant passons `error` en paramètre et observons le résultat:
Maintenant passons `error` en paramètre et observons le résultat :
```shell
```none
$ ./script.sh error
Enter passphrase for key '/home/user/.ssh/key.ed25519':
Create SSH main connection wih socket /tmp/Al77btSXKf
@ -167,9 +164,9 @@ Close SSH main connection
`launch_command` appelée sans paramètre conduit à la sortie de notre script avec
un code supérieur à 0. Cette sortie est capturée par `trap` qui lance aussi la
fonction de nettoyage. Vérifions le code de retour de notre script:
fonction de nettoyage. Vérifions le code de retour de notre script :
```ssh
```none
echo $?
31
```
@ -179,26 +176,23 @@ lorsqu'on l'exécute sans paramètre.
### Interrompre l'exécution
Enfin observons ce qui se passe lorsque l'on interrompt l'exécution du script avec
Ctrl+C:
Enfin observons ce qui se passe lorsque l'on interrompt l'exécution du script
avec Ctrl+C:
```shell
```none
$ ./script.sh
Create SSH main connection wih socket /tmp/0gFlBD6siZ
Enter passphrase for key '/home/user/.ssh/key.ed25519':
Message N°1 from 192.168.0.254
Message N°2 from 192.168.0.254
^CClose SSH main connection
$ echo $?
0
```
Ici encore tout se passe comme prévu, sauf que le code de retour est 0, il
faudrait pouvoir changer se comportement afin de signifier que le script ne
s'est pas termine comme prévu.
```shell
$ echo $?
0
```
s'est pas termine comme prévu et retourner un code supérieur à 0.
## Différencier les pièges en fonction du signal
@ -209,7 +203,7 @@ petit peu notre script
### Gérer le signal `SIGINT`
Nous allons ajouter une fonction spécifique pour le signal juste après
`cleanup`:
`cleanup` :
```bash
process_int(){
@ -220,7 +214,7 @@ process_int(){
### ajouter un piège
Maintenant nous n'avons plus qu'a ajouter un piège:
Maintenant nous n'avons plus qu'a ajouter un piège :
```bash
# [...]
@ -232,7 +226,7 @@ trap process_int INT
Et voilà, lors de l'exécution notre script et son interruption tout fonctionne
comme prévu:
```shell
```none
$ ./script.sh
Create SSH main connection wih socket /tmp/0gFlBD6siZ
Enter passphrase for key '/home/user/.ssh/key.ed25519':
@ -240,17 +234,19 @@ Message N°1 from 192.168.0.254
Message N°2 from 192.168.0.254
^CERROR: Script interrupted by user (SIGINT)
Close SSH main connection
$ echo $?
255
```
Le message de notre fonction `process_int` s'affiche et la fonction `cleanup` se
lance automatiquement.
## Vérifier la connexion au master avec un signal
Il est possible d'utiliser tout un tas de signaux et de les intercepter avec
`trap`. Intéressons nous maintenant à `SIGUSR1`. C'est avec `SIGUSR2` des
signaux servant pour ce que l'on veut. Nous voulons afficher l'était de la
connexion SSH master. Rajoutons la fonction suivante après `launch_command`:
`trap`. Intéressons nous maintenant à `SIGUSR1`. C'est -- avec `SIGUSR2` -- un
signal servant pour ce que l'on veut. Utilisons le pour afficher l'état de la
connexion SSH master. Rajoutons la fonction suivante après `launch_command` :
```bash
# [...]
@ -262,7 +258,7 @@ check_conn() {
#[...]
```
Puis de modifier le début de notre script comme ceci:
Puis de modifier le début de notre script comme ceci :
```bash
# [...]
@ -281,11 +277,10 @@ piégeons notre signal avec `trap` pour exécuter `check_conn`.
Afin de disposer de plus de temps pour lancer la commande kill
Afin d'avoir le temps de lancer la commande `kill`, augmentons de 20 le nombre
de tour de boucle effectué comme ci-dessous:
de tour de boucle effectué comme ci-dessous :
```bash
# [...]
for (( i=1; i<=20; i++ ))
do
launch_command "echo 'Message N°$i from $server'"
@ -297,8 +292,8 @@ done
D'abord lançons le script et notons le numéros de PID:
```shell
$ ./sscript.sh
```none
$ ./script.sh
Current PID: 9499
Create SSH main connection wih socket /tmp/A4IdltbuxY
Enter passphrase for key '/home/user/.ssh/key.ed25519':
@ -306,14 +301,14 @@ Message N°1 from 192.168.0.254
```
Puis dans un second terminal il nous suffit d'envoyer le signal:
```shell
```none
kill -USR1 9499
```
Le signal est alors reçu par notre script qui va donc exécuter la fonction
attachée:
attachée :
```shell
```none
[...]
Message N°6 from 192.168.0.254
Message N°7 from 192.168.0.254
@ -325,12 +320,12 @@ Et continuer son exécution ensuite.
## En conclusion
Tout au long ce cet article, nous avons vu ce qu'était un signal et comment en
Tout au long ce cet article, nous avons vu ce qu'est un signal et comment en
intercepter un (et même plusieurs) dans un script écrit en Bash. Bien entendu il
est possible d'utiliser les signaux dans d'autre langages, la façon de procéder
est similaire.
Le nettoyage des traces laissées par un script qui ne se termine pas de la façon
attendue est la principale utilisation documentée ci et là dans différents
tutoriaux. Mais ce peut être un outils intéressant de communication
inter-processus dans vos scripts.
**Le nettoyage des traces laissées par un script** est la principale utilisation
documentée ci-et-là dans différents tutoriaux. Mais les possibilités offertes
par ce système de communication inter-processus dans vos script vont bien au
delà de ce simple usage. J'espère vous l'avois montré ici.