Estimated reading time: 5 minutes
Au début, on écrit des scripts avec des valeurs en dur : le dossier à sauvegarder, le nombre de jours à conserver, l’adresse du serveur. Ça marche, jusqu’au jour où on veut le réutiliser pour un autre dossier. Alors on copie le script, on change deux lignes, et on se retrouve avec trois versions presque identiques.
La solution : donner des arguments au script. Cet article fait le tour de ce qu’il faut savoir, du plus simple au plus confortable.
Les arguments positionnels
Quand tu lances ./script.sh a b c, bash range ce que tu as tapé dans des variables spéciales :
| Variable |
Contenu |
$0 |
le nom du script |
$1, $2, … |
le premier, le deuxième… argument |
$# |
le nombre d’arguments |
"$@" |
tous les arguments, chacun correctement séparé |
$? |
le code de retour de la dernière commande |
Un exemple minimal :
#!/usr/bin/env bash
set -euo pipefail
dossier="${1:?Usage : $0 DOSSIER [JOURS]}"
jours="${2:-30}"
echo "Je nettoierais $dossier (fichiers de plus de $jours jours)"
Deux notations à retenir, très pratiques avec set -u :
${2:-30} : « la valeur de $2, ou 30 si elle est absente ».
${1:?message} : « la valeur de $1, ou arrêter avec ce message si elle est absente ».
C’est suffisant pour un script de deux lignes. Dès qu’il y a plus de deux paramètres, ou des paramètres facultatifs, les arguments positionnels deviennent pénibles : qui se souvient si c’est script.sh 30 /srv ou script.sh /srv 30 ?
getopts : les options courtes (-d, -n)
getopts est intégré à bash. Il lit des options comme -d /srv -j 30 -n. Voici un script complet de nettoyage, avec aide et vérifications.
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <&2; usage >&2; exit 2 ;;
?) echo "Option inconnue : -$OPTARG" >&2; usage >&2; exit 2 ;;
esac
done
shift $((OPTIND - 1))
[[ -d "$dossier" ]] || { echo "Dossier introuvable : $dossier" >&2; exit 1; }
[[ "$jours" =~ ^[0-9]+$ ]] || { echo "-j attend un nombre entier." >&2; exit 2; }
if (( simulation )); then
find "$dossier" -type f -mtime +"$jours" -print
else
find "$dossier" -type f -mtime +"$jours" -print -delete
fi
Comment lire la ligne getopts ":d:j:nh" opt :
- Le
: au tout début active la gestion silencieuse des erreurs : c’est toi qui affiches les messages (cas : et ? dans le case).
- Une lettre suivie de
: (d:, j:) attend une valeur, disponible dans $OPTARG.
- Une lettre seule (
n, h) est un interrupteur.
Après la boucle, shift $((OPTIND - 1)) retire les options traitées : il ne reste dans $@ que les arguments « normaux » (par exemple une liste de fichiers).
Quelques essais :
./nettoyer.sh -h # affiche l'aide
./nettoyer.sh -n # simulation avec les valeurs par défaut
./nettoyer.sh -d /srv/photos -j 90 -n
Le mode simulation (-n) est le réflexe le plus utile pour un script qui supprime ou déplace des choses : on voit ce qui serait fait, avant de le faire pour de vrai.
Les options longues (--dossier, --dry-run)
getopts ne gère pas les options longues. Quand on en veut, on écrit soi-même la boucle, avec case et shift :
#!/usr/bin/env bash
set -euo pipefail
dossier="/srv/sauvegardes"
jours=30
simulation=0
while (( $# > 0 )); do
case "$1" in
-d|--dossier) dossier="${2:?--dossier attend une valeur}"; shift 2 ;;
-j|--jours) jours="${2:?--jours attend une valeur}"; shift 2 ;;
-n|--dry-run) simulation=1; shift ;;
-h|--help) echo "Usage : $0 [--dossier D] [--jours N] [--dry-run]"; exit 0 ;;
--) shift; break ;;
-*) echo "Option inconnue : $1" >&2; exit 2 ;;
*) break ;;
esac
done
echo "dossier=$dossier jours=$jours simulation=$simulation reste=$*"
Ce que fait chaque shift : il fait « avancer » la liste d’arguments. shift 2 retire l’option et sa valeur. À la fin, $@ contient ce qui n’a pas été reconnu comme une option.
C’est un peu plus long que getopts, mais c’est lisible, et ça ne dépend d’aucun outil externe.
Lire une valeur depuis l’environnement
Un troisième canal, très utile pour les secrets ou les réglages qui changent peu : les variables d’environnement.
NTFY_URL="${NTFY_URL:-}" # vide si non défini
if [[ -n "$NTFY_URL" ]]; then
curl -fsS -d "Script terminé" "$NTFY_URL" >/dev/null
fi
On les passe ainsi : NTFY_URL=https://ntfy.sh/mon-canal ./script.sh. L’avantage : un mot de passe ou un jeton passé en argument est visible par tous les utilisateurs de la machine dans la liste des processus (ps), alors qu’une variable d’environnement l’est beaucoup moins. Pour un jeton, évite donc l’argument de ligne de commande.
Les codes de retour : parler aux autres programmes
Un script bien élevé renvoie un code de retour :
0 : tout s’est bien passé ;
1 : erreur « générale » (le travail a échoué) ;
2 : mauvais usage (option inconnue, argument manquant), par convention.
C’est ce que lisent cron, systemd, et les scripts qui t’appellent :
if ./nettoyer.sh -n -d /srv/photos; then
echo "ok"
else
echo "échec (code $?)"
fi
Récapitulatif : que choisir ?
| Besoin |
Outil |
| Un ou deux paramètres obligatoires |
$1, $2 avec ${1:?…} |
| Des paramètres facultatifs avec valeurs par défaut |
${2:-valeur} |
| Plusieurs options courtes |
getopts |
Options longues (--dry-run) |
boucle while + case + shift |
| Secrets, réglages stables |
variables d’environnement |
Dans le prochain article, on utilise tout ça pour écrire un vrai script de sauvegarde avec rsync.
Related Articles

Un script bash qui marche, c'est facile. Un script qui échoue proprement, nettoie derrière lui et se relit dans six mois, ça demande cinq habitudes. Voici le squelette complet.

Un script de dix lignes, un cron et ntfy : de quoi recevoir une notification sur ton téléphone quand un disque se remplit ou qu'un service tombe.

Avant d'installer Claude Code, j'utilisais Claude.ai dans un onglet du navigateur, à côté de mon…
Articles similaires
· · ·