# Bash : comment récupérer directement le code d'erreur d'une commande pour le mettre dans une condition

**URL:** <https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827>\
**Category:** Programmation\
**Created:** [Janvier 15, 2025, 4:17 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827 "2025-01-15T16:17:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![fluo](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/e9bcb4/32.png) [@fluo](https://www.debian-fr.org/u/fluo)\
**Post date:** [Janvier 15, 2025, 4:17 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/1 "2025-01-15T16:17:23Z")

</div>

Bonjour à tous,

j’ai cette commande pour scanner les réseaux wifi :

`# iw dev wlo1 scan`

Je sais que pour avoir le code d’erreur d’une commande, il faut utiliser la variable `$?`

Le problème, est que je souhaite exécuter plusieurs fois cette commande iw dev wlo1 scan (en utilisant une boucle while) tant que son code d’erreur est supérieur à 0, comme ceci :

```
while [[`iw dev wlo1 scan` -gt 0]]
do
  sleep 1
done

```

mais dans la condition du while, je sais que mettre `iw dev wlo1 scan` -gt 0 est faux, car ce que je veux c’est avoir le code d’erreur de la commande iw dev wlo1 scan dans la condition du while.

Une idée ? Merci d’avance

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Janvier 15, 2025, 4:49 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/2 "2025-01-15T16:49:33Z")

</div>

au hasard si tu teste juste après l’execution :

```auto
$?

```

Sinon tu peux aussi faire ça pour récupérer le résultat d’une commande :

```auto
resultat=$(command)
echo "$resultat"

```

---

<div class="post-metadata">

**Author:** ![Sputnik93](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/35a633/32.png) [@Sputnik93](https://www.debian-fr.org/u/Sputnik93)\
**Post date:** [Janvier 15, 2025, 9:27 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/3 "2025-01-15T21:27:30Z")

</div>

> [@fluo](#):
>
> Je sais que pour avoir le code d’erreur d’une commande, il faut utiliser la variable `$?`

C’est plutôt le code de sortie, en fait. Généralement si c’est 0 ça signifie que la commande s’est exécutée sans erreur, et si c’est 1 il y a eu une erreur. Mais selon les commandes, les codes de sortie peuvent avoir des significations différentes (je ne sais pas s’il existe un genre de standard).

> [@Clochette](#):
>
> Sinon tu peux aussi faire ça pour récupérer le résultat d’une commande :
> 
> ```auto
> resultat=$(command)
> echo "$resultat"
> 
> ```

Il veut le code de sortie, pas le résultat au sens de la sortie générée.

> [@fluo](#):
>
> mais dans la condition du while, je sais que mettre `iw dev wlo1 scan` -gt 0 est faux, car ce que je veux c’est avoir le code d’erreur de la commande iw dev wlo1 scan dans la condition du while.

En fait, dans une boucle while, bash teste à chaque itération si la condition est vérifiée. Et une commande exécutée sans erreur **est** une condition valide.  
Tu peux donc faire

```auto
while iw dev wlo1 scan ; do
    sleep 1
done

```

Tant que `iw dev wlo1 scan` sera vraie (c’est-à-dire avec un code de sortie égal à 0), les instructions dans la boucle seront exécutées. Si à une itération le code de sortie est différent de 0, la condition ne sera plus vraie et la boucle sera interrompue.

EDIT: j’ai lu un peu vite, si tu veux que les instructions dans la boucle soient exécutées lorsque la commande `iw dev wlo1 scan`sort avec erreur, tu peux faire:

```auto
while ! iw dev wlo1 scan ; do
    sleep 1
done

```

---

<div class="post-metadata">

**Author:** ![AnonymousCoward](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f9ae1b/32.png) [@AnonymousCoward](https://www.debian-fr.org/u/AnonymousCoward)\
**Post date:** [Janvier 15, 2025, 9:58 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/4 "2025-01-15T21:58:08Z")

</div>

C’est tout à fait ça.

En Python, un entier valant 0 serait converti en booléen valant False. Et un entier de toute autre valeur serait converti en True. C’est l’exact inverse avec Bash.

Par exemple :

```bash
$ false; echo $?
1

```

```bash
$ true; echo $?
0

```

En fait, c’est plutôt les tests que l’on peut écrire en utilisant les crochets simples ou doubles qui fonctionnent en renvoyant des codes d’état. Exemples :

```bash
$ [-a .bashrc]; echo $?
0

```

```bash
$ [[-a .bashrc]]; echo $?
0

```

ou encore

```bash
$ test -a .bashrc; echo $?
0

```

–  
AnonymousCoward

---

<div class="post-metadata">

**Author:** ![Zargos](https://www.debian-fr.org/user_avatar/www.debian-fr.org/zargos/32/10889_2.png) [@Zargos](https://www.debian-fr.org/u/Zargos)\
**Post date:** [Janvier 16, 2025, 9:16 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/5 "2025-01-16T09:16:59Z")

</div>

Bonjour,  
@fluo , pourquoi veut tu faiore durer pour avoir le code d’erreur?  
Car à partir du moment ou la commande est executé et la main rendu à l’environnement, le code d’erreur est généré.

---

<div class="post-metadata">

**Author:** ![fluo](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/e9bcb4/32.png) [@fluo](https://www.debian-fr.org/u/fluo)\
**Post date:** [Janvier 16, 2025, 1:04 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/6 "2025-01-16T13:04:29Z")

</div>

Merci pour tous les éléments de réponses, effectivement, on peut faire :

```
while ! iw dev wlo1 scan 2> /dev/null
do 
	sleep 1
	echo "Scan en cours..."
done

```

La raison de ce code est qu’il fait suite à ces commandes :

```
ip link set wlo1 down
iw dev wlo1 set type managed
ip link set wlo1 up

```

Et donc si toute suite après la commande ip link set wlo1 up, je lance la commande iw dev wlo1 scan, j’aurais cette erreur :

`command failed: Device or resource busy (-16)`

, parce que l’interface wlo1 met du temps pour être en état «&nbsp;up&nbsp;».

J’aurais pu faire un simple sleep comme ceci :

```
sleep 3
iw dev wlo1 scan

```

, mais si un sleep de 3 secondes n’est pas suffisant pour que wlo1 soit à «&nbsp;up&nbsp;», il faudrait mettre un sleep à 4 secondes, ou à 5 secondes.

Mais pour ne pas à définir en dur la durée du sleep, je préfère utiliser une boucle while pour vérifier si wlo1 est prêt pour le scan, donc «&nbsp;tant&nbsp;» que wlo1 n’est «&nbsp;pas encore&nbsp;» prêt pour le scan, càd si la commande iw dev wlo1 scan 2\> /dev/null retourne false, alors on revérifie à nouveau cette condition 1 seconde plus tard , sinon si ça ne retourne pas false, c’est que wlo1 est prêt pour le scan, et donc va scanner et on sort donc de la boucle while.

Sinon, si on veut en plus faire un egrep pour filtrer la sortie en cas de succès :

```
while true
do 
	#On exécute la commande :
	if ! iw dev wlo1 scan 2> /dev/null | egrep "BSS ([a-zA-Z0-9]{2}:)|SSID|freq|rates|signal|primary channel|WPA|RSN" 
	
	#Et donc si elle retourne une erreur, on passe à la prochaine itération de la boucle while :
	then
		sleep 1
		echo "Scan en cours..."
	else
		#Alors la commande sera exécuté sans erreur, et donc on sort de la boucle while :
		break
	fi	
	
done
```

---

<div class="post-metadata">

**Author:** ![Zargos](https://www.debian-fr.org/user_avatar/www.debian-fr.org/zargos/32/10889_2.png) [@Zargos](https://www.debian-fr.org/u/Zargos)\
**Post date:** [Janvier 16, 2025, 1:33 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/7 "2025-01-16T13:33:09Z")

</div>

```auto
ip link set wlo1 down && iw dev wlo1 set type managed && ip link set wlo1 up

```

Ainsi il ne fait la commande suivante que si le retour de la commande précédente est true.

---

<div class="post-metadata">

**Author:** ![fluo](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/e9bcb4/32.png) [@fluo](https://www.debian-fr.org/u/fluo)\
**Post date:** [Janvier 16, 2025, 1:41 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/8 "2025-01-16T13:41:57Z")

</div>

Merci pour ta réponse

j’ai testé :

`ip link set wlo1 down && iw dev wlo1 set type managed && ip link set wlo1 up && iw dev wlo1 scan && echo "scan réussi"`

ça me retourne :

command failed: Device or resource busy (-16)

je pense que c’est parce que «&nbsp;&&&nbsp;» n’est pas asynchrone, càd «&nbsp;n’attend&nbsp;» pas que iw dev wlo1 scan retourne true pour pouvoir exécuter echo «&nbsp;scan réussi&nbsp;»

---

<div class="post-metadata">

**Author:** ![Zargos](https://www.debian-fr.org/user_avatar/www.debian-fr.org/zargos/32/10889_2.png) [@Zargos](https://www.debian-fr.org/u/Zargos)\
**Post date:** [Janvier 16, 2025, 1:54 UTC](https://www.debian-fr.org/t/bash-comment-recuperer-directement-le-code-derreur-dune-commande-pour-le-mettre-dans-une-condition/90827/9 "2025-01-16T13:54:26Z")

</div>

peut être alors:

```auto
ip link set wlo1 down && wait $! && iw dev wlo1 set type managed && wait $! && ip link set wlo1 up

```

$! est le numéro de process de la commande précédente il me semble.  
mais je ne sais pas si ca fonctionne.  
Ou bien sous la forme:

```auto
ip link set wlo1 down
wait $!
iw dev wlo1 set type managed
wait $!
ip link set wlo1 up

```
