Le secret de la première ligne des scripts Linux : Que signifient #!/usr/bin/env bash et #!/bin/bash ?
Lorsque vous rédigez un script sous Linux, il est courant d'ajouter cette ligne en haut :
#!/usr/bin/env bash
ou encore
#!/bin/bash
À première vue, cela ressemble à un simple commentaire... Mais quelle est la véritable nature de cette ligne ? Et surtout, quelles sont les différences entre ces deux formes ? Dans cet article, nous allons décortiquer cette ligne mystérieuse pour comprendre son rôle et savoir quand utiliser l'une ou l'autre.
1. Ce n'est pas un commentaire : Qu'est-ce que le shebang ?
Cette ligne, commençant par #!, est appelée shebang.
#!/bin/bash
Du point de vue du shell, puisque cela commence par #, cela ressemble clairement à un « commentaire ». Cependant, pour le système d'exploitation (le noyau), il ne s'agit pas d'un commentaire, mais d'une directive qui indique :
« Où trouver le programme interpréteur pour exécuter ce script. »
Autrement dit :
#!/bin/bash→ « Exécute ce fichier avec/bin/bash. »#!/usr/bin/env bash→ « Trouve l'interpréteurbashviaenvet exécute ce fichier avec celui-ci. »
2. Comment le noyau exécute-t-il un script ?
En simplifiant le processus d'exécution, cela se déroule comme suit :
- L'utilisateur exécute un script avec les droits d'exécution.
chmod +x script.sh
./script.sh
- Le noyau lit
script.sh. - Il vérifie si les deux premiers caractères du fichier sont
#!. - Si c'est le cas, il interprète le reste de la ligne comme :
- « Le chemin de l'interpréteur + ses arguments »
- Et exécute ce programme en lui passant le chemin du fichier script comme argument.
Par exemple, si la première ligne de script.sh est :
#!/bin/bash
Le noyau effectue en réalité une action que l'on peut conceptualiser ainsi :
/bin/bash script.sh
Autrement dit, le noyau exécute une action similaire à celle que nous ferions en tapant directement bash script.sh.
Note : Il ne doit pas y avoir d'espace avant
#!/. Le premier caractère du fichier doit être#, et le second!.
3. Signification et caractéristiques de #!/bin/bash
C'est la forme la plus couramment rencontrée.
#!/bin/bash
Signification
- « Ce script est un script bash, et
bashse trouve dans/bin/bash. » - Le noyau exécutera toujours
/bin/bashpour ce script.
Avantages
- Clarté : L'utilisation systématique de
/bin/bashrend prévisible la version de bash qui sera employée. - Performance/Simplicité : Le script est exécuté directement, sans passer par
env, ce qui élimine le processus de recherche du chemin. - Sur de nombreuses distributions Linux,
/bin/bashest considéré comme un « emplacement standard » de facto.
Inconvénients
-
Manque de portabilité
-
Sur certains systèmes, bash peut se trouver à un autre emplacement, comme
/usr/bin/bashou/usr/local/bin/bash. - Certains systèmes peuvent ne pas avoir bash du tout, et ne disposer que de
/bin/sh. - Les chemins peuvent différer, notamment sur macOS, les systèmes basés sur BSD, NixOS et certains environnements de conteneurs.
4. Signification et caractéristiques de #!/usr/bin/env bash
C'est la forme la plus couramment rencontrée dans les scripts modernes.
#!/usr/bin/env bash
L'élément clé ici est /usr/bin/env.
-
envest un utilitaire qui aide à « définir/vérifier les variables d'environnement + rechercher des programmes dans le PATH ». -
On peut considérer que le noyau exécute réellement ceci :
bash
/usr/bin/env bash script.sh
envexamine la variable d'environnementPATHdu système pour trouver et exécuter l'exécutablebash.
Avantages
- Portabilité (fonctionne bien dans divers environnements)
- Que bash se trouve dans
/bin/bash,/usr/bin/bash, ou/usr/local/bin/bash, envle trouvera tant qu'il est correctement enregistré dans le PATH.
- Utilisation de la version de bash adaptée à l'environnement utilisateur
- Si l'utilisateur a personnalisé son
PATHpour utiliser une version spécifique de bash en priorité, c'est cette version qui sera utilisée.
- Utilisation du même modèle pour Python et d'autres langages
python
#!/usr/bin/env python3
Inconvénients
- Nécessite la présence de /usr/bin/env
- Bien qu'il soit présent sur presque tous les systèmes Unix/Linux modernes, il pourrait manquer dans des environnements très spécifiques.
- Un interpréteur différent peut être sélectionné en fonction du PATH
- Si la configuration du PATH est corrompue ou si une version inattendue de bash est trouvée en premier, une version non désirée pourrait être exécutée.
- Nécessite une attention particulière en matière de sécurité
- Dans des environnements très sensibles à la sécurité, la préférence peut aller aux chemins absolus plutôt qu'à la recherche d'interpréteurs basée sur le PATH.
5. Comparaison des deux approches
Voici un tableau comparatif simplifié.
| Critère | #!/bin/bash | #!/usr/bin/env bash |
|---|---|---|
| Méthode de spécification de l'interpréteur | Chemin absolu fixe | Recherche via PATH |
| Portabilité (compatibilité multi-systèmes) | Faible (casse si le chemin diffère) | Élevée (OK si bash est dans le PATH) |
| Quelle version de bash est utilisée | Toujours /bin/bash |
Le premier bash trouvé dans le PATH |
| Garantie de la version souhaitée | Relativement facile | Peut varier selon l'état du PATH |
| Sécurité/Contrôle | Plus fort (chemin fixe) | Légèrement plus souple (dépend du PATH) |
| Tendance générale actuelle | Style relativement ancien | Plus souvent recommandé de nos jours |
6. Quand utiliser quelle approche ?
Pour répondre à la question « En fin de compte, que dois-je utiliser ? », voici une ventilation par situation.
1) Scripts personnels / de développement d'équipe (environnements de développement courants)
- Généralement, la recommandation est la suivante :
bash
#!/usr/bin/env bash
-
Raisons :
-
L'emplacement de bash peut varier sur les serveurs gérés par les développeurs, les environnements locaux, les environnements CI, etc.
- La recherche et l'exécution basées sur le PATH sont plus flexibles, et les outils/scripts modernes préfèrent cette approche.
2) Scripts d'exploitation adaptés à un environnement serveur spécifique
-
Par exemple, si tous les serveurs de l'entreprise ont bash installé en commun dans
/bin/bash, -
Et si l'environnement serveur est relativement fixe :
bash
#!/bin/bash
-
Raisons :
-
Assure l'utilisation du même interpréteur en permanence.
- Réduit les comportements inattendus dus aux modifications du PATH.
3) Si vous souhaitez une portabilité maximale ?
-
Si vous envisagez un environnement où « bash pourrait ne pas être installé du tout », il faut d'abord se demander si un script dépendant de bash est la bonne approche.
-
Si possible, écrivez en
sh:
bash
#!/bin/sh
- Cette approche fonctionnera dans un éventail beaucoup plus large d'environnements. Cependant, il ne faut pas utiliser la syntaxe propre à bash (
[[ ]], tableaux, traitement étendu des chaînes de caractères, etc.).
7. Conseils pratiques pour l'utilisation de #!/usr/bin/env bash
1) Méthode d'exécution du script
Pour utiliser correctement le shebang, il est préférable de ne pas faire ceci :
bash script.sh # ← L'exécution de cette manière rend le shebang presque inutile
Mais plutôt de l'utiliser comme suit :
chmod +x script.sh # Accorder les droits d'exécution
./script.sh # Exécuter directement
C'est ainsi que le noyau lira le #! et utilisera l'interpréteur spécifié.
2) Vérification du passage des arguments
Prenons l'exemple de test.sh créé comme suit :
#!/usr/bin/env bash
echo "Interpréteur: $0"
echo "Arguments: $@"
Exécution :
chmod +x test.sh
./test.sh hello world
Sortie :
Interpréteur: ./test.sh
Arguments: hello world
Ici, $0 représente le « chemin du fichier script lui-même », et il suffit de se rappeler que le noyau l'exécute en réalité comme /usr/bin/env bash test.sh hello world.
8. Foire aux questions
J'ai déjà vu des scripts écrits sans shebang. Est-ce normal ?
-
C'est exact, le shebang n'est pas toujours nécessaire.
-
Si vous exécutez le script en spécifiant directement l'interpréteur, comme ci-dessous, le shebang n'est pas nécessaire. Même s'il est présent, il sera ignoré.
bash
bash myscript.sh
python3 myscript.py
- Cependant, si vous souhaitez l'exécuter comme suit, il est absolument indispensable :
bash
./myscript.sh
./myscript.py
- En particulier, pour les scripts destinés à être utilisés comme des « outils » par d'autres, le shebang est pratiquement obligatoire.
« J'ai vu #!/bin/env fonctionner aussi, pas seulement #!/usr/bin/env ? »
- Sur certains systèmes,
/bin/envpeut exister. - Cependant,
/usr/bin/envest généralement l'emplacement standard le plus universel. - À moins d'une raison spécifique, il est plus sûr d'utiliser
#!/usr/bin/env ….
9. Résumé
#!/usr/bin/env bashou#!/bin/bashne sont pas des commentaires, mais des directives qui indiquent au noyau avec quel interpréteur exécuter le script.-
#!/bin/bash -
Utilise toujours
/bin/bash→ Prévisible dans un environnement fixe, mais potentiellement moins portable. -
#!/usr/bin/env bash -
Cherche bash dans le
PATH→ Plus flexible et portable, mais dépend de l'état du PATH. - Pour la rédaction de scripts « modernes » dans des environnements de développement/déploiement courants, il est recommandé d'utiliser
#!/usr/bin/env bashpar défaut.
