Skip to content

Introduction aux scripts

Un script Shell est un fichier texte contenant une série d'instructions exécutées séquentiellement. Il peut être créé avec n'importe quel éditeur de texte (Vim, Nano, Emacs, Gedit, etc.).

Premier script

Shebang

La première ligne d'un script indique l'interpréteur à utiliser.

On utilise #! suivi du chemin absolu de l'interpréteur.

On peut également utiliser /usr/bin/env pour rechercher l'interpréteur dans le PATH, ce qui rend le script plus portable.

Exemples:

bash
#!/usr/bin/env bash     # recommandé (recherche bash dans le PATH)
# ou
#!/bin/bash             # chemin absolu classique

Autres langages de scripts:

  • awk: #!/usr/bin/awk -f
  • sed: #!/usr/bin/sed -f
  • python3: #!/usr/bin/env python3

Enregistrement et exécution

  1. Créez un fichier hello.sh et mettez le shebang et une commande:
bash
#!/usr/bin/env bash
echo "Bonjour!"
  1. Rendez-le exécutable et lancez-le:
bash
$ chmod +x hello.sh
$ ./hello.sh

Si le fichier n'est pas dans le PATH et que vous êtes dans le dossier courant, le ./ est nécessaire.

PATH

Le PATH est une variable d'environnement contenant une liste de dossiers séparés par des deux-points :. Lorsque vous tapez une commande, le shell cherche l'exécutable dans ces dossiers.

Le PATH peut être affiché avec:

bash
$ echo $PATH

La configuration du PATH se fait dans des fichiers comme ~/.profile, ~/.bashrc, ou /etc/profile selon le système et le shell utilisé.

Sous Debian, On peut modifier cette variable dans le fichier /etc/profile pour tous les utilisateurs ou dans ~/.profile pour seulement vous.

Codes de sortie (exit)

exit N termine le script avec le code N. Convention: 0 = succès, non‑zéro = erreur.

bash
#!/usr/bin/env bash
if [[ -z ${1:-} ]]; then
	echo "Erreur: un argument est requis" >&2
	exit 1
fi
echo "Argument: $1"
exit 0

Le code de sortie de la dernière commande est disponible dans $?.

Expansion de paramètres ${var:-def}

:- dans ${var:-def} signifie: utiliser def si var est non définie ou vide; sinon utiliser la valeur de var.

Variantes utiles:

  • ${var-def}: n'utilise def que si var est non définie (si var vaut "", on garde "").
  • ${var:=def}: comme :- mais affecte aussi var=def.

Exemples:

bash
nom=${1:-"inconnu"}
echo "Bonjour, $nom"   # si aucun argument: "inconnu"

Variables

En Bash, les variables sont non typées (traitées comme des chaînes par défaut).

Déclaration et utilisation

bash
nom=Aminata         # pas d'espaces autour de =
echo $nom           # expansion simple
echo "$nom"         # expansion protégée (recommandé)
echo ${nom} Garneau # accolades pour délimiter le nom

Convention de nommage

MAJUSCULES : Variables constantes ou de configuration

  • Valeurs qui ne doivent pas changer pendant l'exécution
  • Paramètres par défaut
  • Variables d'environnement

minuscules : Variables locales et temporaires

  • Valeurs qui changent durant l'exécution
  • Variables de boucle, compteurs, etc.

Portée et export

Par défaut, une variable est locale au shell courant. Pour la rendre visible aux processus enfants (ex.: un script lancé), utilisez export:

bash
var=42
export var
bash -c 'echo "var vaut: $var"'  # affiche 42
# bash -c permet d'exécuter une commande dans un nouveau shell

Supprimer une variable: unset var.

Paramètres positionnels et spéciaux

Lorsque vous lancez un script/commande avec des arguments:

  • $0 = nom de la commande/script
  • $1, $2, ... = arguments
  • $# = nombre d'arguments
  • $* ou $@ = tous les arguments ("$@" préserve les séparations)
  • $$ = PID du shell/script courant
  • $! = PID du dernier job en arrière‑plan

Exemple:

bash
#!/usr/bin/env bash
echo "Script: $0, nb args: $#"
echo "Tous: $*"
for a in "$@"; do
	echo "arg: $a"
done

'script1'

Variables d'environnement

Variables globales fournies par le système, par ex. HOME, USER, PATH, LANG, PWD.

Par convention les variables d’environnement sont en MAJUSCULES.

Afficher: echo "$HOME".

Ajouter un dossier au PATH pour la session courante:

bash
$ export PATH="$PATH:$HOME/bin"

Pour rendre cela persistant, ajoutez‑le à ~/.profile ou ~/.bashrc selon votre distribution.

Substitutions de commandes et arithmétique

Le résultat d’une commande peut être mis dans une variable.

Mettre la sortie d'une commande dans une variable:

bash
$ now=$(date +%F-%T)
$ echo $now
2025-10-30-16:36:57

$ files_count=$(ls -1 | wc -l)
$ echo "Il y a $files_count fichiers dans le dossier."
Il y a 10 fichiers dans le dossier.

Évaluer une expression arithmétique, utiliser (( )):

bash
compte=$(( 1 + 2 * 3 ))   # 7

String !

Si une chaîne non numérique est utilisée dans (( )), elle est traitée comme 0, sauf si c'est un nom de variable existant.

Comparaisons

Le test s'effectue généralement avec [ ] (alias de la commande test) ou [[ ]] (test amélioré de Bash).

Nombres

Opérateurs:

  • -eq → égal (equal)
  • -ne → différent (not equal)
  • -lt → moins que (less than)
  • -le → moins ou égal (less or equal)
  • -gt → plus que (greater than)
  • -ge → plus ou égal (greater or equal)
bash
[ 3 -eq 3 ]
[ 2 -lt 3 ] && echo "OK"

On peut aussi utiliser < et > avec échappement dans [ ], ou sans échappement dans [[ ]]:

bash
[ 2 \< 3 ]
[[ 2 < 3 ]]

Chaînes

  • -z str → vide
  • -n str → non vide
  • == et != pour égalité/inegalité (dans [[ ]])
bash
[[ -z "$s" ]] && echo "vide"
[[ -n "$s" ]] && echo "non vide"

Toujours citer les variables avec des guillemets ("$var") pour éviter les surprises lorsqu'elles sont vides ou qu'elles contiennent des espaces.

Guillemets

Avec des guillemets, la valeur est prise comme une seule chaîne, même si elle contient des espaces ou est vide.

Sans guillemets, la chaîne est divisée en plusieurs mots selon les espaces.

Exemples:

bash
test="un deux"
printf '[%s]\n' $test      # -> [un] puis [deux] (2 arguments)
printf '[%s]\n' "$test"    # -> [un deux] (1 argument)
bash
files="*.md"
echo $files       # -> liste tous les .md du dossier
echo "$files"     # -> affiche littéralement *.md

Expressions régulières

Dans [[ ]], =~ permet de tester une regex:

bash
if [[ $code_postal =~ ^[A-Za-z][0-9][A-Za-z][[:space:]]?[0-9][A-Za-z][0-9]$ ]]; then
  echo "Code postal valide"
  else
  echo "Code postal invalide"
fi

Astuce: stocker la regex dans une variable pour plus de lisibilité:

bash
re='^[A-Za-z][0-9][A-Za-z][[:space:]]?[0-9][A-Za-z][0-9]$'
if [[ $code_postal =~ $re ]]; then
  echo "Code postal valide"
  else
  echo "Code postal invalide"
fi

Fichiers

  • -f chemin → fichier régulier existe
  • -d chemin → dossier existe
  • -e chemin → fichier ou dossier existe
bash
if [[ -d "$HOME" ]]; then
  echo "Dossier ok"
fi

Structures de contrôle

if / elif / else

bash
if [[ condition ]]; then
	commandes
elif [[ autre_condition ]]; then
	commandes
else
	commandes
fi

for

Deux formes usuelles:

bash
# itération sur une liste
for nom in Aminata bob charlie; do
	echo "$nom"
done

# style arithmétique
for (( i=1; i<=5; i++ )); do
	echo "$i"
done

while

bash
while command|[[ test ]]; do
	commandes
done

Exemple:

bash
compteur=3
while (( compteur > 0 )); do
	echo "reste: $compteur"
	((compteur--))
done

Bonnes pratiques rapides

  • Toujours commencer par un shebang correct.
  • Utiliser des guillements pour les variables: "$var".
  • Valider les entrées et gérer les erreurs; retourner des codes d'erreur significatifs (exit 1, etc.).

Pratique 💃

  1. Écrire un script qui salue un utilisateur passé en argument, et qui échoue proprement si aucun argument n'est fourni.
bash
#!/bin/bash 
# Correction exercice 1

# Si le nombre d'arguments n'est pas 1, afficher l'usage et quitter
if [[ $# -ne 1 ]]; then
    echo "Usage: $0 <nom_utilisateur>" >&2 
    exit 1
fi
echo "Bonjour, $1!"
  1. Écrire un script qui:
    • vérifie l'existence d'un dossier passé en paramètre,
    • liste ses fichiers,
    • crée une archive tar.gz datée.

Exemple d'utilisation de tar:

bash
tar -czf archive.tar.gz -C /chemin/du/dossier .
-c crée une nouvelle archive
-z compresse avec gzip
-f spécifie le nom du fichier à créer
-C spécifie le dossier source
. liste tout le contenu du dossier
bash
#!/bin/bash 
# Correction exercice 2

# Si le nombre d'arguments n'est pas 1, afficher l'usage et quitter
if [[ $# -ne 1 ]]; then
    echo "Usage: $0 <dossier>" >&2
    exit 1
fi

# Initialise la variable dir avec le nom du dossier
dir="$1"
# Vérification de l'existence du dossier
if [[ ! -d "$dir" ]]; then
    echo "Erreur: le dossier '$dir' n'existe pas." >&2
    exit 1
fi  
# Liste les fichiers dans le dossier
echo "Fichiers dans '$dir':"
ls -l "$dir"
# Crée une archive tar.gz datée
archive_name="$(basename "$dir")_$(date +%F).tar.gz"
tar -czf "$archive_name" -C "$dir" .
echo "Archive créée: $archive_name"
  1. Écrire un script qui, avec une boucle for, parcourt chaque argument (chemin de fichier ou dossier) et affiche son type:
    • "fichier" (+ sa taille en octets)
    • "dossier"
    • "inconnu" si rien de tout ça

Utiliser stat -c%s ou wc -c pour obtenir la taille d'un fichier.

On doit pouvoir l'exécuter comme ceci:

bash
$ ./script3.sh /etc/passwd /etc /path/unknown
1) fichier      : /etc/passwd (2450 octets)
2) dossier      : /etc
3) inconnu      : /path/unknown
bash
#!/usr/bin/env bash

if [[ $# -eq 0 ]]; then
	echo "Usage: $0 <chemin>..." >&2
	exit 1
fi

i=1
for path in "$@"; do
	if [[ -f "$path" ]]; then
		size=$(stat -c%s "$path" 2>/dev/null || wc -c <"$path")
		echo "$i) fichier      : $path ($size octets)"
	elif [[ -d "$path" ]]; then
		echo "$i) dossier      : $path"
	else
		echo "$i) inconnu      : $path"
	fi
	((i++))
done
  1. Écrire un script qui valide un « code » passé en argument avec une regex: trois lettres minuscules suivies de deux chiffres (ex.: abc12).

Exemples d'exécution:

bash
$ ./script4.sh abc12
OK: format valide
$ ./script4.sh A1
ERREUR: format invalide
bash
#!/usr/bin/env bash

if [[ $# -ne 1 ]]; then
	echo "Usage: $0 <code>" >&2
	exit 1
fi

code=$1
re='^[a-z]{3}[0-9]{2}$'
if [[ $code =~ $re ]]; then
	echo "OK: format valide"
else
	echo "ERREUR: format invalide" >&2
	exit 2
fi

Quiz 🎉

Ce quiz teste vos connaissances sur les scripts Linux.

0 questions - Bonne chance ! 🔒

.