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 Category: sysadmin
Tags: bash, script, pl-fr Tags: bash, script, signaux, pl-fr
Date: 2022-11-15 8:30 Date: 2022-11-15 8:30
Cover: assets/backgrounds/ackbar-trap.jpg 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 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! une suite. Et bien la voici!
Dans cette suite, il va être question de faire un peu le ménage lorsque votre Dans cette suite, il va être question de signaux, de **"trap"** et bien entendu
script s'arrête, que se soit gracieusement ou pas, mais pas que... de Bash.
## Dis, c'est quoi un signal ## 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 signal SIGINT au processus en cours lui signifiant d'interrompre séance tenante
toute action. Chaque signal est associé à un numéro 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 Signal | Valeur | Action | Commentaire
--------|--------|--------|---------------------------------------------------- --------|--------|--------|----------------------------------------------------
SIGHUP | 1 | Term | Déconnexion du terminal ou fin du processus de contrôle SIGHUP | 1 | Term | Déconnexion du terminal ou fin du processus de contrôle
SIGINT | 2 | Term | Interruption depuis le clavier `CTRL + C` 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 SIGILL | 4 | Core | Instruction illégale
SIGABRT | 6 | Core | Signal darrêt depuis abort(3) SIGABRT | 6 | Core | Signal darrêt depuis abort(3)
SIGFPE | 8 | Core | Erreur mathématique virgule flottante 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 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. le ménage et terminer la connexion maitre.
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
# Changer ces valeurs par celles adapté à votre configuration # Changer ces valeurs par celles adapté à votre configuration
@ -114,9 +114,6 @@ do
done 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 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 de l'appel de cette dernière nous trouvons notre instruction `trap`. Elle
appelle la commande `cleanup` lorsque le signal `EXIT` est envoyé. 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 ### Laisser le script finir normalement
Appeler le script sans argument et le laisser se terminer sans intervenir est 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 $ ./script.sh
Create SSH main connection wih socket /tmp/TvCuLSzkMN Create SSH main connection wih socket /tmp/TvCuLSzkMN
Enter passphrase for key '/home/user/.ssh/key.ed25519': 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 ### 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 $ ./script.sh error
Enter passphrase for key '/home/user/.ssh/key.ed25519': Enter passphrase for key '/home/user/.ssh/key.ed25519':
Create SSH main connection wih socket /tmp/Al77btSXKf 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 `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 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 $? echo $?
31 31
``` ```
@ -179,26 +176,23 @@ lorsqu'on l'exécute sans paramètre.
### Interrompre l'exécution ### Interrompre l'exécution
Enfin observons ce qui se passe lorsque l'on interrompt l'exécution du script avec Enfin observons ce qui se passe lorsque l'on interrompt l'exécution du script
Ctrl+C: avec Ctrl+C:
```shell ```none
$ ./script.sh $ ./script.sh
Create SSH main connection wih socket /tmp/0gFlBD6siZ Create SSH main connection wih socket /tmp/0gFlBD6siZ
Enter passphrase for key '/home/user/.ssh/key.ed25519': Enter passphrase for key '/home/user/.ssh/key.ed25519':
Message N°1 from 192.168.0.254 Message N°1 from 192.168.0.254
Message N°2 from 192.168.0.254 Message N°2 from 192.168.0.254
^CClose SSH main connection ^CClose SSH main connection
$ echo $?
0
``` ```
Ici encore tout se passe comme prévu, sauf que le code de retour est 0, il 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 faudrait pouvoir changer se comportement afin de signifier que le script ne
s'est pas termine comme prévu. s'est pas termine comme prévu et retourner un code supérieur à 0.
```shell
$ echo $?
0
```
## Différencier les pièges en fonction du signal ## Différencier les pièges en fonction du signal
@ -209,7 +203,7 @@ petit peu notre script
### Gérer le signal `SIGINT` ### Gérer le signal `SIGINT`
Nous allons ajouter une fonction spécifique pour le signal juste après Nous allons ajouter une fonction spécifique pour le signal juste après
`cleanup`: `cleanup` :
```bash ```bash
process_int(){ process_int(){
@ -220,7 +214,7 @@ process_int(){
### ajouter un piège ### 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 ```bash
# [...] # [...]
@ -232,7 +226,7 @@ trap process_int INT
Et voilà, lors de l'exécution notre script et son interruption tout fonctionne Et voilà, lors de l'exécution notre script et son interruption tout fonctionne
comme prévu: comme prévu:
```shell ```none
$ ./script.sh $ ./script.sh
Create SSH main connection wih socket /tmp/0gFlBD6siZ Create SSH main connection wih socket /tmp/0gFlBD6siZ
Enter passphrase for key '/home/user/.ssh/key.ed25519': 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 Message N°2 from 192.168.0.254
^CERROR: Script interrupted by user (SIGINT) ^CERROR: Script interrupted by user (SIGINT)
Close SSH main connection Close SSH main connection
$ echo $? $ echo $?
255 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 ## Vérifier la connexion au master avec un signal
Il est possible d'utiliser tout un tas de signaux et de les intercepter avec 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 `trap`. Intéressons nous maintenant à `SIGUSR1`. C'est -- avec `SIGUSR2` -- un
signaux servant pour ce que l'on veut. Nous voulons afficher l'était de la 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`: connexion SSH master. Rajoutons la fonction suivante après `launch_command` :
```bash ```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 ```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 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 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 ```bash
# [...] # [...]
for (( i=1; i<=20; i++ )) for (( i=1; i<=20; i++ ))
do do
launch_command "echo 'Message N°$i from $server'" 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: D'abord lançons le script et notons le numéros de PID:
```shell ```none
$ ./sscript.sh $ ./script.sh
Current PID: 9499 Current PID: 9499
Create SSH main connection wih socket /tmp/A4IdltbuxY Create SSH main connection wih socket /tmp/A4IdltbuxY
Enter passphrase for key '/home/user/.ssh/key.ed25519': 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: Puis dans un second terminal il nous suffit d'envoyer le signal:
```shell ```none
kill -USR1 9499 kill -USR1 9499
``` ```
Le signal est alors reçu par notre script qui va donc exécuter la fonction 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°6 from 192.168.0.254
Message N°7 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 ## 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 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 possible d'utiliser les signaux dans d'autre langages, la façon de procéder
est similaire. est similaire.
Le nettoyage des traces laissées par un script qui ne se termine pas de la façon **Le nettoyage des traces laissées par un script** est la principale utilisation
attendue est la principale utilisation documentée ci et là dans différents documentée ci-et-là dans différents tutoriaux. Mais les possibilités offertes
tutoriaux. Mais ce peut être un outils intéressant de communication par ce système de communication inter-processus dans vos script vont bien au
inter-processus dans vos scripts. delà de ce simple usage. J'espère vous l'avois montré ici.