Objectifs
- Comprendre la différence entre le shell standard POSIX (
sh) etbash. - Identifier les fonctionnalités spécifiques à Bash (les “bashisms”).
- Choisir le bon shebang (
#!/bin/shvs#!/bin/bash) en fonction de l’objectif de votre script. - Écrire des scripts plus portables qui fonctionnent sur une plus grande variété de systèmes Unix.
Explications détaillées
Notions clés
POSIX sh : Le Dénominateur Commun
POSIX est une famille de standards qui vise à maintenir la compatibilité entre les systèmes d’exploitation de type Unix. Le shell POSIX, ou /bin/sh, définit un ensemble de commandes et de fonctionnalités de base que tous les shells compatibles doivent supporter.
Pensez à sh comme le “français fondamental”. Un script écrit en pur sh a de très bonnes chances de fonctionner sur presque n’importe quel système (Linux, macOS, BSD, Solaris…).
bash : Un sur-ensemble puissant
bash (Bourne-Again SHell) est le shell par défaut sur la plupart des systèmes Linux et macOS. Il est entièrement compatible avec sh, mais il ajoute de nombreuses fonctionnalités très pratiques qui ne font pas partie du standard POSIX. Ces fonctionnalités sont appelées des “bashisms”.
Les “Bashisms” courants
Ce sont des fonctionnalités que vous utilisez probablement tous les jours, mais qui ne fonctionneront pas dans un script #!/bin/sh sur un système où /bin/sh n’est pas bash.
[[ ... ]]: La version moderne et sûre de[ ... ]. Ensh, il faut utiliser[.- Les tableaux (
declare -a) et tableaux associatifs (declare -A). Le shell POSIX ne connaît pas les tableaux. - L’expansion des accolades
{a..c}ou{un,deux}. - La substitution de processus
<(...). - Les boucles de style C
for ((...)). letet((...))pour l’arithmétique.- Le mot-clé
functionpour définir des fonctions (ensh, on utilisenom() { ... }). - Certaines options de commandes, comme
echo -e.
/bin/sh : Une surprise potentielle
Sur de nombreux systèmes (comme CentOS ou macOS), /bin/sh est un lien symbolique vers /bin/bash. Sur ces systèmes, un script #!/bin/sh avec des bashisms fonctionnera… par chance.
Mais sur d’autres, comme Debian ou Ubuntu, /bin/sh pointe vers dash, un shell beaucoup plus léger et strictement POSIX. Sur ces systèmes, les bashisms provoqueront des erreurs de syntaxe.
Le Shebang : Déclarer son intention
La première ligne de votre script est cruciale.
#!/bin/sh(ou#!/usr/bin/env sh) : Vous promettez que votre script est portable et n’utilise que des fonctionnalités POSIX.#!/bin/bash(ou#!/usr/bin/env bash) : Vous déclarez que votre script a besoin debashet que vous avez le droit d’utiliser ses fonctionnalités étendues.
Syntaxe / Usages
# Script portable avec /bin/sh
# Utilise [ ... ], des tests simples et une syntaxe POSIX
#--------------------------------------------
#!/bin/sh
set -eu
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <nom>" >&2
exit 1
fi
NOM="$1"
echo "Bonjour, $NOM"
# Script moderne avec /bin/bash
# Utilise [[ ... ]], un tableau et une expansion de paramètre
#--------------------------------------------
#!/usr/bin/env bash
set -euo pipefail
args=("$@")
if [[ "${#args[@]}" -ne 1 ]]; then
echo "Usage: $0 <nom>" >&2
exit 1
fi
NOM="${args[0]}"
echo "Bonjour, ${NOM^}" # Met la première lettre en majuscule (bashism)
Bonnes pratiques
- Soyez explicite avec le shebang. Si vous utilisez des bashisms, mettez
#!/usr/bin/env bash. - Pour les scripts que vous devez distribuer ou qui doivent tourner sur des serveurs variés (potentiellement anciens ou minimalistes), faites l’effort de les écrire en POSIX
sh. - Pour vos scripts personnels ou internes à votre entreprise (où
bashest la norme), n’hésitez pas à utiliser les bashisms. Ils rendent le code plus sûr et plus lisible ([[ ... ]], tableaux, etc.). - Utilisez l’outil
shellcheck. Il est excellent pour détecter les problèmes de portabilité. Il vous avertira si vous utilisez un bashism dans un script déclaré ensh.
Pièges courants
- Le piège du
/bin/shqui pointe versbash: Développer sur un système où/bin/shestbash, écrire un script#!/bin/shplein de bashisms, et le voir échouer en production où/bin/shestdash. - Les options de commandes non portables : Les options de certaines commandes standards comme
ps,sedoudatepeuvent varier entre les versions GNU (Linux) et BSD (macOS).
Exercices
-
Vérifiez votre système :
- Exécutez la commande
ls -l /bin/sh. Vers quoi pointe-t-elle sur votre système ? Est-cebash,dash, ou autre chose ?
- Exécutez la commande
-
Script de test de portabilité :
- Créez un fichier
test_portabilite.shavec le shebang#!/bin/sh. - À l’intérieur, écrivez une ligne qui utilise un bashism évident, comme
mon_tableau=("a" "b")ouif [[ 1 == 1 ]]. - Essayez de l’exécuter avec
bash ./test_portabilite.sh(ça devrait marcher). - Maintenant, essayez de l’exécuter avec un shell strictement POSIX comme
dash(si disponible :dash ./test_portabilite.sh). Observez l’erreur.
- Créez un fichier
-
Réécriture portable :
- Prenez ce script Bash :
#!/usr/bin/env bash set -eu if [[ $# -eq 0 ]]; then echo "Aucun argument" exit 1 fi for arg in "${@}"; do echo "Arg: ${arg,,}" # tout en minuscules done - Réécrivez-le pour qu’il soit compatible
#!/bin/sh. (Indices :[[->[,,,->tr '[:upper:]' '[:lower:]').
- Prenez ce script Bash :