# 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.