Comprendre /bin/bash : shell, interpréteur et shebang

/bin/bash désigne un fichier exécutable : Bash, un shell qui lit des commandes et des scripts. Le terminal est la fenêtre où vous saisissez ces commandes ; il ne se confond ni avec Bash ni avec le fichier lancé. La ligne #!, appelée shebang, sert ensuite à choisir l’interpréteur lors d’un lancement direct.
Sommaire
Pour comprendre un script qui commence par #!/bin/bash ou #!/usr/bin/env bash, il faut donc séparer quatre éléments : le chemin, le programme, le shell demandé et la manière de lancer le fichier.
Que désigne vraiment /bin/bash ?
Un chemin décrit un emplacement dans l’arborescence. Dans /bin/bash, /bin est le répertoire indiqué et bash le nom du programme à cet emplacement. Bash est l’abréviation de Bourne Again SHell : c’est un shell, c’est-à-dire un programme qui interprète une ligne, applique ses règles de découpage, d’expansion et de redirection, puis lance une commande.
Le terminal fournit l’interface texte. Bash peut être le shell ouvert dans cette interface, mais une même fenêtre peut lancer un autre shell. Un processus est l’exécution en cours d’un programme ; une commande est ce que le shell doit traiter. Ces mots décrivent des objets différents, même lorsqu’ils apparaissent sur la même ligne.
Sur une installation Linux, vérifiez le chemin et la version au lieu de déduire le résultat du seul nom :
command -v bash
readlink -f /bin/bash
bash --version
/usr/bin/bash
/usr/bin/bash
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
Ces trois lignes ont été relevées le 18 septembre 2026. La première demande au shell quel exécutable il trouve, la deuxième suit le chemin réel de /bin/bash et la troisième donne la version de Bash. Le manuel de Bash décrit ensuite comment ce shell lit et exécute une commande.
Bash, sh et le shell : trois noms qui ne se remplacent pas
bash demande le programme Bash trouvé dans le PATH. sh désigne l’interface de shell standard décrite par POSIX, mais la commande concrète et ses extensions dépendent du système. /bin/bash et /bin/sh sont, eux, des chemins précis. Les confondre revient à confondre un contrat de langage, un nom recherché et une adresse de fichier.
| Écriture | Ce qu’elle demande | Point à vérifier |
|---|---|---|
bash |
Bash trouvé dans le PATH |
la version renvoyée par bash --version |
sh |
la commande sh trouvée dans le PATH |
l’implémentation réellement appelée |
/bin/bash |
le fichier à ce chemin | le chemin peut être un lien symbolique |
/bin/sh |
le fichier à ce chemin | la cible de readlink -f /bin/sh |
Sur l’installation utilisée pour l’essai, readlink -f /bin/sh a renvoyé /usr/bin/dash. Cela ne transforme pas dash en définition universelle de sh : c’est la correspondance de cette installation. La spécification POSIX de l’utilitaire sh décrit le langage attendu ; la documentation de Bash et POSIX explique aussi le cas où Bash est invoqué sous le nom sh.
Le shebang ne fait pas ce que vous pensez
Les deux premiers caractères #! indiquent un interpréteur pour un fichier lancé comme un exécutable. Avec #!/bin/bash, le système passe le fichier à Bash situé à ce chemin. Avec #!/usr/bin/env bash, il lance d’abord env, qui cherche ensuite bash dans le PATH.
Cette ligne intervient quand vous lancez directement un fichier exécutable, par exemple ./probe-bash.sh. Elle ne choisit pas l’interpréteur lorsque vous écrivez déjà bash probe-bash.sh ou sh probe-bash.sh : ces deux commandes donnent explicitement le fichier à un programme différent. Dans ces cas, la ligne #! reste au début du fichier, mais elle ne sert plus à sélectionner ce programme.
Le mécanisme du noyau et la forme de la ligne sont détaillés dans la page execve(2). Le manuel GNU consacré aux scripts shell rappelle de son côté qu’un lancement direct demande le bit exécutable et qu’un fichier peut nommer son interpréteur avec #!.
Le même fichier, trois lancements
Un cas très court rend la différence visible. Dans un dossier temporaire, créez probe-bash.sh avec ce contenu, puis rendez-le exécutable :
#!/usr/bin/env bash
set -e
values=(pwd ls)
printf 'interpreter=%s\n' "$BASH_VERSION"
printf 'syntax=%s\n' "${values[*]}"
chmod +x probe-bash.sh
./probe-bash.sh
bash probe-bash.sh
sh probe-bash.sh
Voici le résultat relevé avec ce même fichier le 18 septembre 2026 :
| Lancement | Sortie utile | Statut |
|---|---|---|
./probe-bash.sh |
interpreter=5.2.21(1)-releasesyntax=pwd ls |
0 |
bash probe-bash.sh |
interpreter=5.2.21(1)-releasesyntax=pwd ls |
0 |
sh probe-bash.sh |
Syntax error: "(" unexpected |
2 |
Le tableau values=(pwd ls) est une syntaxe Bash. Le lancement direct suit le shebang, et l’appel explicite à Bash lit le fichier avec le même interpréteur. L’appel explicite à sh utilise ici /usr/bin/dash, qui s’arrête sur cette syntaxe à la ligne 3. Le code 2 décrit ce fichier et cette installation ; il ne signifie pas que tous les programmes appelés sh échoueront de la même manière.
Choisir entre /bin/bash et /usr/bin/env bash
#!/bin/bash fixe l’adresse de l’interpréteur. C’est un choix lisible lorsque vous maîtrisez la machine cible et que Bash existe à cet emplacement. Le chemin peut être un lien symbolique, mais il reste le chemin demandé par le fichier.
#!/usr/bin/env bash fixe l’adresse de env, puis lui demande de trouver bash dans le PATH. Ce choix suit l’organisation de l’installation et peut trouver un autre Bash si l’ordre du PATH change. Il ne rend pas un script portable à lui seul : env peut manquer à cet emplacement, Bash peut être absent et la syntaxe utilisée peut exiger une version précise.
Choisissez le chemin absolu pour une cible connue et maîtrisée ; préférez la recherche dans le PATH lorsque l’environnement documente cette convention. Le manuel GNU env décrit ce lanceur et ses arguments. Dans les deux cas, vérifiez le Bash réellement exécuté avant de distribuer le fichier.
Le nom .sh ne suffit pas à identifier le shell
L’extension .sh est une convention de nommage, pas une instruction adressée au système. Un fichier nommé outil.sh peut contenir de la syntaxe Bash, de la syntaxe POSIX ou un mélange qui échouera selon le programme choisi. La première ligne, la syntaxe et la commande de lancement doivent être cohérentes.
Pour vérifier seulement l’analyse Bash sans exécuter le fichier, utilisez :
bash -n probe-bash.sh
bash -n demande à Bash de parcourir la syntaxe et de ne pas lancer les commandes. Il ne teste ni les fichiers attendus, ni les droits, ni les commandes externes. À l’inverse, sh probe-bash.sh demande explicitement à un autre shell de lire le fichier et peut révéler une syntaxe Bash incompatible avec son langage.
Vérifier avant de copier un script
Lisez la première ligne avant de lancer quoi que ce soit. Si elle annonce Bash, vérifiez command -v bash et bash --version, puis repérez les constructions qui ne font pas partie du shell que vous comptiez utiliser. Si le fichier doit être lancé directement, vérifiez aussi son bit exécutable avec ls -l.
Lorsque le besoin est simplement de comprendre une commande et sa sortie, les commandes Linux de base donnent un exercice séparé des fichiers importants. Pour replacer le shell dans la fenêtre où vous travaillez, les repères du terminal Linux distinguent l’interface, l’invite et le programme qui interprète la ligne.
Un script compris peut ensuite servir à répéter une opération locale : la page automatiser une petite routine montre comment passer d’une suite de commandes à une routine contrôlée, sans confondre le shell avec l’automatisation elle-même.
L’essai présenté porte sur Bash 5.2.21 et le sh de l’installation mesurée ; il ne décrit pas le comportement de toutes les distributions ni de tous les shells.