Files
abonnel-www/351da6e5-004e-4311-ae8b-ebe91a913b3e/index.md
T

183 lines
5.9 KiB
Markdown

# L'opérateur `&&` — exécution conditionnelle
L'opérateur `&&` permet d'enchaîner deux commandes en exécutant la seconde **uniquement si la première a réussi**. C'est un opérateur logique « ET » qui s'appuie sur le **code de retour** (*exit status*) des commandes.
## Rappel : le code de retour
Chaque commande Unix renvoie un code de retour en fin d'exécution :
- **`0`** = succès
- **toute autre valeur (1 à 255)** = échec (le chiffre précise souvent le type d'erreur)
On peut consulter ce code avec la variable spéciale `$?` :
```bash
~ $ ls /tmp
fichier1.txt fichier2.txt
~ $ echo $?
0 # ✅ succès
~ $ ls /dossier_inexistant
ls: impossible d'accéder à '/dossier_inexistant': Aucun fichier ou dossier de ce type
~ $ echo $?
2 # ❌ échec
```
C'est ce code que `&&` examine pour décider s'il exécute ou non la commande suivante.
## Syntaxe et fonctionnement
```bash
commande1 && commande2
```
- Si `commande1` réussit (code `0`) → `commande2` est exécutée.
- Si `commande1` échoue (code ≠ `0`) → `commande2` est **ignorée**.
### Exemple basique
```bash
~ $ mkdir mon_projet && cd mon_projet
~/mon_projet $
```
Ici, on entre dans le dossier `mon_projet` **uniquement** s'il a été créé avec succès. Si `mkdir` échoue (par exemple parce que le dossier existe déjà), le `cd` n'est pas tenté — ce qui évite de se retrouver dans un état imprévu.
### Comparaison avec et sans `&&`
```bash
# ❌ Sans &&, les deux commandes s'exécutent quoi qu'il arrive
~ $ mkdir mon_projet ; cd mon_projet
mkdir: impossible de créer le répertoire « mon_projet »: Le fichier existe
~/mon_projet $ # cd a quand même été exécuté
# ✅ Avec &&, cd n'est pas exécuté si mkdir échoue
~ $ mkdir mon_projet && cd mon_projet
mkdir: impossible de créer le répertoire « mon_projet »: Le fichier existe
~ $ # on est resté dans le dossier d'origine
```
Le point-virgule `;` enchaîne sans condition, alors que `&&` enchaîne **sous condition de succès**.
## Cas d'usage courants
### 1. Compiler puis exécuter un programme
```bash
~ $ gcc -o monprog monprog.c && ./monprog
```
Le programme n'est lancé que si la compilation a réussi. Si `gcc` échoue, on évite d'exécuter une version obsolète ou inexistante.
### 2. Mettre à jour puis installer un paquet
```bash
~ $ sudo apt update && sudo apt install nginx
```
L'installation n'est tentée que si la mise à jour de la liste des paquets s'est bien passée. Cela évite d'installer une version périmée si les dépôts sont temporairement inaccessibles.
### 3. Vérifier l'existence d'un fichier avant de l'utiliser
```bash
~ $ test -f config.txt && source config.txt
```
Le fichier `config.txt` n'est chargé que s'il existe vraiment. Sinon, on évite une erreur bruyante.
### 4. Sauvegarder avant de modifier
```bash
~ $ cp important.txt important.txt.bak && nano important.txt
```
L'édition n'est lancée qu'après la sauvegarde réussie de l'original.
## Chaîner plusieurs `&&`
On peut enchaîner autant de `&&` que nécessaire. L'exécution s'arrête **dès qu'une commande échoue** :
```bash
~ $ cd /tmp && mkdir test && cd test && touch fichier.txt && ls
fichier.txt
```
Si l'une de ces étapes échoue, toutes les suivantes sont sautées. C'est particulièrement utile dans les scripts de déploiement :
```bash
#!/bin/bash
git pull \
&& npm install \
&& npm run build \
&& npm test \
&& npm run deploy
```
Le déploiement n'a lieu que si toutes les étapes précédentes (récupération du code, installation, build, tests) ont réussi. Au moindre échec, la chaîne s'interrompt.
## L'opérateur complémentaire `||`
Pour bien comprendre `&&`, il faut le mettre en parallèle avec `||` (« OU »), qui fait l'inverse : il exécute la seconde commande **uniquement si la première a échoué**.
```bash
~ $ ls /dossier_inexistant || echo "Le dossier n'existe pas !"
ls: impossible d'accéder à '/dossier_inexistant': Aucun fichier ou dossier de ce type
Le dossier n'existe pas !
```
### Combinaison `&&` et `||` : un « if/else » en une ligne
On peut combiner les deux pour exprimer un test conditionnel concis :
```bash
~ $ test -f config.txt && echo "Fichier trouvé" || echo "Fichier absent"
```
- Si `config.txt` existe → affiche « Fichier trouvé ».
- Sinon → affiche « Fichier absent ».
⚠️ **Attention à un piège** : si la commande après `&&` échoue elle-même, la branche `||` sera quand même exécutée. Exemple :
```bash
~ $ test -f config.txt && echo "trouvé" > /fichier/interdit || echo "absent"
absent # 🤔 alors que config.txt existait bien !
```
Ici, `test -f` a réussi, mais l'écriture dans `/fichier/interdit` a échoué — donc `||` s'est déclenché à tort. Pour un vrai if/else sans ce risque, mieux vaut utiliser la structure complète :
```bash
if test -f config.txt; then
echo "trouvé"
else
echo "absent"
fi
```
## Vérifier soi-même le comportement
Petit test pour bien visualiser le mécanisme :
```bash
~ $ true && echo "ça passe"
ça passe
~ $ false && echo "ça passe"
# rien ne s'affiche
~ $ true || echo "ça passe"
# rien ne s'affiche
~ $ false || echo "ça passe"
ça passe
```
`true` est une commande qui réussit toujours (code `0`) et `false` une commande qui échoue toujours (code `1`) — idéales pour comprendre les opérateurs logiques.
## À retenir
| Opérateur | Signification | Exécute la 2ᵉ commande si... |
|-----------|---------------|--------------------------------------|
| `;` | Enchaînement | ...toujours (peu importe le résultat)|
| `&&` | ET logique | ...la 1ʳᵉ a **réussi** (code `0`) |
| `\|\|` | OU logique | ...la 1ʳᵉ a **échoué** (code ≠ `0`) |
`&&` est l'un des outils les plus utilisés en scripting shell : il rend le code à la fois plus court et plus sûr, en empêchant les commandes de s'exécuter dans un contexte d'erreur.