Shell Scripting Bash
Un script shell = fichier texte contenant une séquence de commandes Linux.
Au lieu de taper 50 commandes une par une, on les écrit dans un fichier .sh et on l'exécute.
Pourquoi écrire des scripts ?
Configuration manuelle d'un serveur :
useradd tim → groupadd devops → mkdir projet → touch fichier.txt
→ chmod 750 /chemin → sudo apt install docker → docker run ...
Avec un script : ./setup-server.sh → TOUT est exécuté automatiquement
| Bénéfice | Description |
|---|
| Éviter la répétition | Ne taper qu'une seule fois ce qui se répète |
| Historique | Le script documente la configuration |
| Partage | Partager les instructions avec l'équipe |
| Logique | Conditions, boucles, variables |
| Opérations en masse | Configurer 100 serveurs identiques |
Structure d'un script Bash
#!/bin/bash
echo "Démarrage de la configuration..."
Le Shebang #!
La première ligne définit quel shell interprétera le script :
| Shebang | Shell |
|---|
#!/bin/bash | Bash (Bourne Again Shell) — le plus courant |
#!/bin/sh | Bourne Shell — minimal |
#!/bin/zsh | ZSH |
"Shebang" = contraction de "sharp-bang" (#!) — le # se dit "sharp" et ! se dit "bang".
Créer et exécuter un script
vim setup.sh
echo "Bonjour !"
chmod +x setup.sh
chmod u+x setup.sh
./setup.sh
bash setup.sh
Variables
#!/bin/bash
nom="Alice"
age=30
version=$(cat /etc/os-release | grep VERSION_ID)
echo "Bonjour $nom, vous avez $age ans"
echo "Version OS : $version"
Conditions (if/else)
#!/bin/bash
fichier="config.yaml"
if [ -f "$fichier" ]
then
echo "Le fichier $fichier existe"
else
echo "Le fichier $fichier n'existe pas"
fi
Opérateurs de test de fichiers
| Opérateur | Description |
|---|
-f fichier | Le fichier existe et est un fichier régulier |
-d dossier | Le dossier existe |
-r fichier | Le fichier est lisible |
-w fichier | Le fichier est modifiable |
-x fichier | Le fichier est exécutable |
-s fichier | Le fichier existe et n'est pas vide |
Opérateurs relationnels (nombres)
| Opérateur | Signification |
|---|
-eq | Égal à |
-ne | Différent de |
-gt | Supérieur à |
-lt | Inférieur à |
-ge | Supérieur ou égal |
-le | Inférieur ou égal |
Opérateurs de chaîne
| Opérateur | Signification |
|---|
= | Égal |
!= | Différent |
-z | Chaîne vide |
-n | Chaîne non vide |
#!/bin/bash
count=5
if [ $count -gt 3 ]
then
echo "Count est supérieur à 3"
elif [ $count -eq 3 ]
then
echo "Count est égal à 3"
else
echo "Count est inférieur à 3"
fi
Passages d'arguments
#!/bin/bash
echo "Premier argument : $1"
echo "Deuxième argument : $2"
echo "Tous les arguments : $*"
echo "Nombre d'arguments : $#"
./script.sh alice devops
Boucles
Boucle for
#!/bin/bash
for serveur in web1 web2 web3
do
echo "Configuration de $serveur..."
ssh $serveur "sudo apt update"
done
for fichier in /var/log/*.log
do
echo "Traitement : $fichier"
done
Boucle while
#!/bin/bash
compteur=1
while [ $compteur -le 10 ]
do
echo "Tentative $compteur..."
if curl -s http://mon-service/health | grep "OK"
then
echo "Service disponible !"
break
fi
compteur=$((compteur + 1))
sleep 5
done
Fonctions
#!/bin/bash
creer_utilisateur() {
local username=$1
local groupe=$2
echo "Création de l'utilisateur $username dans $groupe..."
sudo adduser $username
sudo usermod -aG $groupe $username
echo "Utilisateur $username créé avec succès"
}
creer_utilisateur "alice" "devops"
creer_utilisateur "bob" "admin"
Bonnes pratiques pour les fonctions
- Une fonction = une responsabilité (Single Responsibility Principle)
- Utiliser
local pour les variables internes à la fonction
- Ne pas trop de paramètres (difficile à lire)
- Nommer clairement la fonction pour qu'elle soit auto-documentée
Exemple complet — Script de configuration serveur
#!/bin/bash
NOM_UTILISATEUR=$1
NOM_GROUPE=$2
PROJET_DIR="/opt/projet"
if [ $# -lt 2 ]
then
echo "Usage: ./setup.sh <username> <groupname>"
exit 1
fi
echo "=== Configuration du serveur ==="
echo "Création du groupe $NOM_GROUPE..."
sudo groupadd $NOM_GROUPE
echo "Création de l'utilisateur $NOM_UTILISATEUR..."
sudo adduser $NOM_UTILISATEUR
sudo usermod -aG $NOM_GROUPE $NOM_UTILISATEUR
echo "Création du dossier $PROJET_DIR..."
sudo mkdir -p $PROJET_DIR
sudo chown $NOM_UTILISATEUR:$NOM_GROUPE $PROJET_DIR
sudo chmod 770 $PROJET_DIR
echo "Installation de Docker..."
sudo apt update
sudo apt install -y docker.io
sudo usermod -aG docker $NOM_UTILISATEUR
echo "=== Configuration terminée ==="
echo "Utilisateur : $NOM_UTILISATEUR"
echo "Groupe : $NOM_GROUPE"
echo "Dossier : $PROJET_DIR"
chmod +x setup.sh
./setup.sh alice devops
À retenir
- Script = fichier
.sh avec des commandes Linux automatisées
- Shebang
#!/bin/bash = première ligne obligatoire indiquant le shell
chmod +x script.sh = rendre exécutable avant la première exécution
- Variables :
nom="valeur" (sans espaces) ; utiliser avec $nom
$1, $2, $#, $* = paramètres positionnels et métadonnées
[ condition ] = test (équivalent à la commande test)
if/then/else/fi = structure conditionnelle
for var in liste = boucle sur une liste
while condition = boucle tant que la condition est vraie
- Fonctions = blocs réutilisables avec leurs propres variables locales