Vous lancez un script bash qui compile un projet dans un sous-dossier, puis tente de revenir au répertoire initial pour la suite des opérations. Le script plante, ou pire, il continue silencieusement dans le mauvais dossier. Le problème vient rarement de cd lui-même, mais de l’absence de mécanisme fiable pour gérer les allers-retours. C’est précisément le rôle de popd et de la pile de répertoires bash.
La pile de répertoires bash : comprendre pushd et popd avant de les utiliser
Avant de parler de popd, il faut visualiser la pile de répertoires. Imaginez une pile d’assiettes : chaque appel à pushd /un/chemin pose une nouvelle assiette sur le dessus. Chaque appel à popd retire l’assiette du dessus et vous ramène au répertoire qu’elle représentait.
A découvrir également : IA85 Webmail : le guide ultime pour les néophytes
La commande dirs affiche l’état de cette pile à tout moment. L’élément tout en haut correspond au répertoire courant.
Ce qui distingue ce mécanisme d’un simple cd -, c’est sa profondeur. Avec cd -, vous ne pouvez revenir qu’au dernier répertoire visité. Avec la pile, vous pouvez enchaîner trois, quatre ou dix déplacements successifs, puis les dérouler un par un dans l’ordre inverse.
A lire aussi : Guide pour utiliser https://aka.ms/remoteconnect : Connectez vos appareils Microsoft
Voici un exemple concret :
pushd /var/log puis pushd /etc/nginx puis pushd /tmp. À ce stade, la pile contient (du sommet vers la base) : /tmp, /etc/nginx, /var/log, et votre répertoire de départ. Trois appels successifs à popd vous ramènent exactement au point de départ, dans l’ordre inverse.

Popd dans un script bash : pourquoi le changement de dossier échoue silencieusement
Avez-vous déjà eu un script qui supprime des fichiers dans le mauvais répertoire après un cd raté ? Le danger réel de popd (et de pushd) dans un script, c’est leur comportement en cas d’erreur. Par défaut, popd sur une pile vide échoue mais le script continue.
Prenons un cas typique. Un script fait un pushd vers un dossier temporaire, effectue des opérations, puis appelle popd pour revenir. Si le pushd initial a échoué (dossier inexistant, permissions insuffisantes), la pile n’a pas été modifiée. Le popd suivant tente alors de dépiler un élément qui n’existe pas, échoue, et le script reste dans le répertoire courant, quel qu’il soit.
La suite des commandes s’exécute dans un répertoire imprévu. Si cette suite inclut un rm -rf relatif, les conséquences peuvent être sévères.
Activer set -e ne suffit pas toujours
L’option set -e interrompt un script dès qu’une commande retourne un code d’erreur non nul. C’est un premier filet de sécurité. Avec set -e, un popd qui échoue arrête le script au lieu de le laisser dériver.
Le piège : set -e ne s’applique pas aux commandes placées dans une condition if, dans une boucle while ou après un &&. Si votre popd se trouve dans l’une de ces structures, l’erreur est ignorée malgré set -e.
Fiabiliser popd : trois techniques concrètes pour vos scripts
Plutôt que de faire confiance aveuglément à la pile, voici les pratiques qui évitent les erreurs de répertoire en production.
- Vérifier le code retour de pushd avant de continuer : écrivez
pushd /chemin/cible || exit 1. Si le répertoire cible n’existe pas, le script s’arrête immédiatement au lieu d’empiler un état incohérent. - Associer pushd et popd dans un bloc cohérent : chaque
pushddoit avoir sonpopdcorrespondant, comme des parenthèses ouvrantes et fermantes. Unpushdorphelin laisse la pile dans un état imprévisible pour les appels suivants. - Utiliser un sous-shell comme alternative : entourer un bloc de commandes entre parenthèses
( cd /chemin/cible && commande )crée un sous-processus. Le répertoire courant du script principal n’est jamais modifié, ce qui élimine le besoin depopd. Cette approche est souvent plus simple pour les opérations ponctuelles.
Quand préférer le sous-shell à pushd/popd
Le sous-shell convient quand le script doit exécuter quelques commandes dans un autre dossier sans transmettre de variables au reste du script. Les variables définies dans le sous-shell n’existent pas en dehors.
En revanche, pushd/popd reste préférable quand plusieurs déplacements successifs sont nécessaires dans le même processus, par exemple pour un script de déploiement qui enchaîne compilation, tests et copie dans plusieurs répertoires.

Séparer les chemins du code : fichiers de configuration et variables
Une source fréquente de bugs avec popd n’a rien à voir avec la pile elle-même : ce sont les chemins codés en dur dans le script. Quand un chemin change entre l’environnement de développement et la production, le pushd échoue et le popd devient imprévisible.
La parade consiste à externaliser les chemins dans un fichier de configuration chargé au début du script via source config.conf. Le script ne contient plus que des variables ($DEPLOY_DIR, $BUILD_DIR) et la logique reste identique quel que soit l’environnement.
Cette séparation entre la logique et les valeurs réduit les erreurs liées aux répertoires et rend le script réutilisable sans modification entre plusieurs serveurs.
Déboguer la pile de répertoires dans un script bash
Quand un script se comporte de façon inattendue après un popd, deux outils aident à comprendre ce qui se passe.
La commande dirs -v affiche la pile numérotée, avec un index pour chaque élément. Insérez-la à des points stratégiques du script pour vérifier l’état de la pile pendant l’exécution.
L’option set -x active le mode trace : bash affiche chaque commande avant de l’exécuter, y compris les pushd et popd. Combinée avec set -e, cette option permet de repérer exactement à quel moment la pile diverge de l’état attendu.
Un réflexe utile : ajouter dirs -v juste après chaque popd pendant la phase de test, puis retirer ces lignes une fois le script validé.
La pile de répertoires bash n’est pas un gadget : c’est un mécanisme de navigation structuré, adapté aux scripts qui jonglent avec plusieurs dossiers. La condition pour que popd fonctionne de façon fiable tient en une phrase : chaque pushd doit réussir avant que le popd correspondant ne soit appelé. Vérifiez les codes retour, utilisez des sous-shells pour les cas simples, et externalisez vos chemins. Le reste suit.

