Some corrections thanks to PenguoinPdt
From le journal du Hacker
This commit is contained in:
parent
e2603f66e4
commit
9c7a4ff039
1 changed files with 21 additions and 23 deletions
|
@ -1,7 +1,8 @@
|
||||||
Title: Bash avancé: It's a trap!
|
Title: Bash avancé: It's a trap!
|
||||||
Category: sysadmin
|
Category: sysadmin
|
||||||
Tags: bash, script, signaux, pl-fr
|
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
|
Cover: assets/backgrounds/ackbar-trap.jpg
|
||||||
|
|
||||||
Pour l'instant, on ne peut pas dire que 2022 soit une année productive côté
|
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
|
## 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
|
é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
|
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
|
signal SIGINT au processus en cours lui signifiant d'interrompre séance tenante
|
||||||
|
@ -43,18 +44,18 @@ utiliser :
|
||||||
trap "<commande>" <liste_signaux>
|
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.
|
exemple ne peut pas donner lieu à exécution d'une commande.
|
||||||
|
|
||||||
## Dans la vraie vie?
|
## 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
|
persistante à l'aide des options `ControlMaster` et `ContolPath` histoire de
|
||||||
pouvoir lancer plusieurs connexions successives plus rapidement (et sans se
|
pouvoir lancer plusieurs connexions successives plus rapidement (et sans se
|
||||||
ré-identifier).
|
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 maître.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
@ -116,15 +117,15 @@ done
|
||||||
```
|
```
|
||||||
Ce script est disponible en suivant [ce lien]({attach}files/premier_script.sh)
|
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
|
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é.
|
||||||
|
|
||||||
`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`.
|
`ERR`, `DEBUG` ou `RETURN`.
|
||||||
|
|
||||||
Ensuite, si l'argument `error` est passé à notre script, `launch_command` est
|
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
|
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
|
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
|
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 ce comportement afin de signifier que le script ne
|
||||||
s'est pas termine comme prévu et retourner un code supérieur à 0.
|
s'est pas terminé comme prévu et retourner un code supérieur à 0.
|
||||||
|
|
||||||
## Différencier les pièges en fonction du signal
|
## Différencier les pièges en fonction du signal
|
||||||
|
|
||||||
Tout est prévu dans *Bash* pour contourner ce problème : il est possible de
|
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
|
lancer plusieurs commandes `trap`. Modifions un petit peu notre script.
|
||||||
petit peu notre script
|
|
||||||
|
|
||||||
### Gérer le signal `SIGINT`
|
### Gérer le signal `SIGINT`
|
||||||
|
|
||||||
|
@ -257,13 +257,13 @@ connexion SSH master. Rajoutons la fonction suivante après `launch_command` :
|
||||||
# [...]
|
# [...]
|
||||||
check_conn() {
|
check_conn() {
|
||||||
msg "Check connection on ${server}"
|
msg "Check connection on ${server}"
|
||||||
ssh -S "$ssh_sock" -O stop $server
|
ssh -S "$ssh_sock" -O check $server
|
||||||
sleep 10
|
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
|
```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
|
lui envoyer le signal `USR1` avec `kill` depuis un autre terminal. Et enfin
|
||||||
piégeons notre signal avec `trap` pour exécuter `check_conn`.
|
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
|
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 :
|
||||||
|
|
||||||
|
@ -328,9 +326,9 @@ Et continuer son exécution ensuite.
|
||||||
|
|
||||||
## En conclusion
|
## En conclusion
|
||||||
|
|
||||||
Tout au long de cet article, nous avons vu ce qu'était un signal et comment en
|
Tout au long de cet article, nous avons vu ce qu'était un signal et comment
|
||||||
intercepter dans un script écrit en Bash. Bien entendu il est possible
|
l'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
|
d'utiliser les signaux dans d'autres langages, la façon de procéder est
|
||||||
similaire.
|
similaire.
|
||||||
|
|
||||||
**Le nettoyage des traces laissées par un script** est la principale utilisation
|
**Le nettoyage des traces laissées par un script** est la principale utilisation
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue