Some corrections thanks to PenguoinPdt

From le journal du Hacker
This commit is contained in:
Yorick Barbanneau 2022-11-18 12:40:55 +01:00
parent e2603f66e4
commit 9c7a4ff039

View file

@ -1,7 +1,8 @@
Title: Bash avancé: It's a trap!
Category: sysadmin
Tags: bash, script, signaux, pl-fr
Date: 2022-11-15 8:30
Date: 2022-11-16 0:10
Modified: 2022-11-18 9:55
Cover: assets/backgrounds/ackbar-trap.jpg
Pour l'instant, on ne peut pas dire que 2022 soit une année productive côté
@ -14,7 +15,7 @@ de *Bash*.
## Dis, c'est quoi un signal
Un signal est ue sorte de notification envoyée à un processus lorsqu'un
Un signal est une sorte de notification envoyée à un processus lorsqu'un
événement particulier a eu lieu. Plus concrètement, lorsqu'un programme ne
répond 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
@ -43,18 +44,18 @@ utiliser :
trap "<commande>" <liste_signaux>
```
Attention cependant, tous les signaux ne peuvent pas être piégé: `SIGKILL` par
Attention cependant, tous les signaux ne peuvent pas être piégés : `SIGKILL` par
exemple ne peut pas donner lieu à exécution d'une commande.
## Dans la vraie vie?
Prenons un cas concret: un script nécessite l'ouverture d'une connexion SSH en
Prenons un cas concret : un script nécessite l'ouverture d'une connexion SSH
persistante à l'aide des options `ControlMaster` et `ContolPath` histoire de
pouvoir lancer plusieurs connexions successives plus rapidement (et sans se
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.
le ménage et terminer la connexion maître.
```bash
#!/usr/bin/env bash
@ -116,15 +117,15 @@ done
```
Ce script est disponible en suivant [ce lien]({attach}files/premier_script.sh)
La connexion principale est intiée par la fonction `connect`. Juste en dessous
La connexion principale est initié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é.
`EXIT` n'est pas un signal standards su système mais interne à *Bash* comme
`EXIT` n'est pas un signal standard du système mais interne à *Bash* comme
`ERR`, `DEBUG` ou `RETURN`.
Ensuite, si l'argument `error` est passé à notre script, `launch_command` est
exécutée mais sans paramètre, ce qui ga générer une erreur.
exécutée mais sans paramètre, ce qui va générer une erreur.
Enfin notre script exécute 5 fois en boucle la fonction `launch_command` qui
se charge d'afficher un petit message sur la machine distante en utilisant la
@ -193,14 +194,13 @@ $ echo $?
```
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 et retourner un code supérieur à 0.
faudrait pouvoir changer ce comportement afin de signifier que le script ne
s'est pas terminé comme prévu et retourner un code supérieur à 0.
## Différencier les pièges en fonction du signal
Tout est prévu dans *Bash* pour contourner ce problème: il est possible de
lancer plusieurs commandes `trap`. Dans notre script nous allons modifier un
petit peu notre script
Tout est prévu dans *Bash* pour contourner ce problème : il est possible de
lancer plusieurs commandes `trap`. Modifions un petit peu notre script.
### Gérer le signal `SIGINT`
@ -226,7 +226,7 @@ trap process_int INT
```
Et voilà, lors de l'exécution notre script et son interruption tout fonctionne
comme prévu:
comme prévu :
```none
$ ./script.sh
@ -257,13 +257,13 @@ connexion SSH master. Rajoutons la fonction suivante après `launch_command` :
# [...]
check_conn() {
msg "Check connection on ${server}"
ssh -S "$ssh_sock" -O stop $server
ssh -S "$ssh_sock" -O check $server
sleep 10
}
#[...]
```
Puis de modifier le début de notre script comme ceci :
Puis de modifions le début de notre script comme ceci :
```bash
# [...]
@ -279,8 +279,6 @@ Au début nous affichons le PID de notre script, nous allons en avoir besoin pou
lui envoyer le signal `USR1` avec `kill` depuis un autre terminal. Et enfin
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 :
@ -298,7 +296,7 @@ lien]({attach}files/troisieme_script.sh)
### Lancer le script
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 :
```none
$ ./script.sh
@ -307,7 +305,7 @@ Create SSH main connection wih socket /tmp/A4IdltbuxY
Enter passphrase for key '/home/user/.ssh/key.ed25519':
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 :
```none
kill -USR1 9499
@ -328,9 +326,9 @@ Et continuer son exécution ensuite.
## En conclusion
Tout au long de cet article, nous avons vu ce qu'était un signal et comment en
intercepter 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
Tout au long de cet article, nous avons vu ce qu'était un signal et comment
l'intercepter dans un script écrit en Bash. Bien entendu il est possible
d'utiliser les signaux dans d'autres langages, la façon de procéder est
similaire.
**Le nettoyage des traces laissées par un script** est la principale utilisation