Scripting Bash Avancé

Variables, conditions, boucles, fonctions & traitement de texte

Utilisez les flèches, cliquez ou glissez pour naviguer

Objectifs de la leçon

1. Variables Bash

Locales, d'environnement, spéciales

2. Conditions if/elif/else

Tests avec [[ ]], opérateurs, fichiers

3. Boucles for, while, until

Itérer sur fichiers et lignes

4. Fonctions Bash

Arguments, return vs echo, local

5. Pipes, redirections & substitution

>, >>, 2>&1, $(), /dev/null

6. grep, sed, awk

Manipulation avancée de texte

Plan du cours

1

Rappel du contexte

De Git et du terminal basique au scripting Bash avancé

2

Variables Bash

Déclaration, expansion, environnement, variables spéciales

3

Conditions

if/elif/else, test, [[ ]], opérateurs de comparaison

4

Boucles

for, while, until, break, continue

5

Fonctions

Déclaration, arguments, return vs echo, portée locale

6

Pipes, redirections & outils texte

>, >>, 2>&1, $(), grep, sed, awk — live coding

Rappel du contexte

Du terminal basique au scripting avancé

Vous savez déjà : ls, cd, mkdir, git add/commit/push

On passe à la vitesse supérieure

Bash n'est pas qu'un terminal — c'est un langage de programmation

Le langage de glue entre les outils Unix

Premier script Bash

❌ Oublier le shebang = erreur fréquente

#!/bin/bash

# Mon premier script

echo "Hello, World!"

💡 #!/bin/bash = chemin de l'interpréteur — obligatoire!

Puis chmod +x script.sh pour rendre exécutable

Variables Bash

Déclaration, expansion, environnement

nom="Alice"

Pas d'espaces autour du = !

Déclaration et expansion

#!/bin/bash

nom="Alice"

age=30

echo "Bonjour $nom, tu as $age ans"

echo 'Avec quotes simples: $nom ne s''expand pas'

$var

Expansion simple

Bash remplace $var par sa valeur

${var}

Expansion avec accolades

Délimite le nom de la variable

'$var'

Quotes simples

Pas d'expansion — littéral

Pourquoi ${var} plutĂ´t que $var ?

echo "$noms"

❌ Bash cherche la variable $noms — pas $nom

echo "${nom}s"

âś… Les accolades isolent nom du s

# Paramètre par défaut

echo "${nom:-inconnu}" # Si nom vide → "inconnu"

# Sous-chaîne

echo "${nom:0:2}" # 2 premiers caractères

# Longueur

echo "${#nom}" # Nombre de caractères

⚠️ Toujours quoter les variables : "$var" pour éviter le word splitting

Variables d'environnement

Transmises aux processus enfants

export API_KEY="secret123"

echo "Clé: $API_KEY"

# Variables d'environnement communes

echo "HOME: $HOME" # /home/user

echo "PATH: $PATH" # /usr/bin:/bin:...

echo "USER: $USER" # Nom d'utilisateur

đź’ˇ export rend la variable disponible aux sous-processus

Variables spéciales

Le socle du scripting Bash

$? # Code de retour dernier cmd

$# # Nombre d'arguments

$@ # Tous les arguments (tableau)

$* # Tous les arguments (string)

$0 # Nom du script

$1 # Premier argument

$2 # Deuxième argument

$$ # PID du processus

🎯 $? = 0 si succès, ≠0 si erreur — fondamental pour le scripting!

Exemple : Vérifier les arguments

#!/bin/bash

if [[ $# -eq 0 ]]; then

echo "Usage: $0 <nom>"

exit 1

fi

echo "Bonjour, $1!"

✅ Test : ./script.sh → erreur | ./script.sh Alice → OK

Conditions

Prendre des décisions dans vos scripts

[[ ]] plutĂ´t que [ ]

Plus sûrs, plus puissants

Syntaxe if/elif/else

if [[ condition ]]; then

# code si vrai

elif [[ autre_condition ]]; then

# code si elif vrai

else

# code sinon

fi

⚠️ Espaces obligatoires ! [[ $x == 'y' ]] et NON [[$x=='y']]

Opérateurs de comparaison

Chaînes

[[ $a == "$b" ]] # égal

[[ $a != "$b" ]] # différent

[[ -z $a ]] # vide

[[ -n $a ]] # non vide

Nombres

[[ $a -eq $b ]] # égal

[[ $a -ne $b ]] # ≠

[[ $a -lt $b ]] # <

[[ $a -gt $b ]] # >

⚠️ Pour les nombres : -eq et non == !

Tests de fichiers

Vérifier l'existence et le type de fichiers

[[ -f "fichier" ]]

Est un fichier

[[ -d "dossier" ]]

Est un dossier

[[ -e "chemin" ]]

Existe

[[ -x "fichier" ]]

Exécutable

[[ -r "fichier" ]]

Lisible

[[ -w "fichier" ]]

Écriture

đź’ˇ Combinaison : [[ -f "$file" && -r "$file" ]]

Boucles

Répéter, itérer, automatiser

for

Liste connue

while

Condition

until

Inverse de while

La boucle for

for fichier in *.txt; do

echo "Traitement de $fichier..."

done

Style C (numérique)

for ((i=0; i<10; i++)); do

echo $i

done

Sur une liste

for couleur in rouge vert bleu; do

echo $couleur

done

La boucle while

Répéter tant qu'une condition est vraie

count=1

while [[ $count -le 5 ]]; do

echo "Tour numéro $count"

((count++))

done

⚠️ Oublier l'incrémentation = boucle infinie ! Ctrl+C pour sortir

while read — le plus utile

Lire un fichier ligne par ligne

while IFS= read -r ligne; do

echo "Ligne: $ligne"

done < "fichier.txt"

💡 IFS= préserve les espaces, -r évite d'interpréter les backslashes

break & continue

ContrĂ´ler le flux des boucles

break

Sortir de la boucle

continue

Passer au tour suivant

Fonctions Bash

Structurer et réutiliser son code

Une fonction = une machine réutilisable

Déclarer et utiliser une fonction

function saluer {

local nom="$1"

echo "Bonjour, $nom!"

}

saluer "Alice"

$1, $2, ...

Arguments

Positionnels

local

Portée

Variable locale

$?

Code retour

0 = succès

⚠️ return vs echo

La confusion la plus fréquente

return = code de sortie (0-255)

echo = sortie standard (stdout)

return vs echo

❌ Confusion

function get_nom {

return "Alice" # ❌ 0-255 seulement!

}

return ne renvoie qu'un entier (code de sortie)

âś… Solution

function get_nom {

echo "Alice" # âś… stdout

}

nom=$(get_nom) # Capture avec $()

echo → stdout → capture avec $()

🎯 return = entier | echo = texte → capturé avec $( )

Portée des variables

local = variable privée à la fonction

compteur=0

function incrementer {

local compteur=5

echo "Dans la fonction: $compteur"

}

incrementer # Affiche 5

echo "Dehors: $compteur" # Affiche 0

💡 Sans local, la variable globale serait modifiée !

Pipes & Redirections

La puissance d'Unix : composer des outils

Bash = langage de glue

Entre les outils Unix

Redirections

cmd > fichier

stdout → fichier (écrase)

cmd >> fichier

stdout → fichier (ajoute)

cmd 2>&1

stderr → stdout

cmd 2>/dev/null

Ignorer les erreurs

💡 2>&1 = redirige stderr vers stdout — essentiel pour les logs

Substitution de commande $( )

Exécuter une commande et capturer sa sortie dans une variable ou une autre commande

# Stocker le résultat d'une commande

fichiers=$(ls *.txt)

echo "Fichiers TXT: $fichiers"

# Dans une autre commande

echo "Il est $(date +%H:%M)"

Comment ça marche ?

1 Bash exécute la commande $(...)
2 Il remplace $(...) par le stdout
3 La commande extérieure reçoit ce texte

Pipeline : | envoie stdout → stdin

# Lire le fichier | filtrer | compter

cat log.txt | grep "ERROR" | wc -l

# Équivalent avec substitution :

nb_erreurs=$(grep "ERROR" log.txt | wc -l)

echo "Erreurs: $nb_erreurs"

⚠️ $( ) vs backticks ` `

result=$(cmd)

âś… Imbricable : $(echo $(cmd))

result=`cmd`

❌ Ne s'imbrique pas facilement

👉 Toujours préférer $( ) — plus lisible, plus puissant

Exit codes

$? = le socle de la gestion d'erreurs

ls fichier.txt

if [[ $? -eq 0 ]]; then

echo "Succès"

else

echo "Échec"

fi

Codes courants

0 = Succès

1 = Erreur générale

2 = Mauvais usage

127 = Commande introuvable

Chaînage logique : && et ||

Bash évalue le code de retour pour décider d'exécuter la commande suivante

cmd1 ; cmd2

⟶ Exécute cmd2 quoi qu'il arrive

cmd1 && cmd2

⟶ Exécute cmd2 seulement si cmd1 réussit (code 0)

cmd1 || cmd2

⟶ Exécute cmd2 seulement si cmd1 échoue (code ≠ 0)

&& = "ET" logique

mkdir build && cd build

Ne va dans build que si la création a réussi

Rappel : mkdir peut échouer (permission, existant)

|| = "OU" logique

ping -c1 google.com || echo "Hors ligne"

Affiche "Hors ligne" seulement si ping échoue

Ne remplace pas un true if/else, mais idéal pour une action rapide

Combiner && et || = if/else en une ligne

# Version script (ce qu'on a vu avant)

if [[ $? -eq 0 ]]; then echo OK; else echo ÉCHEC; fi

# Version chaînée (idiomatique Bash)

compiler && echo "OK" || echo "Échec"

Live Coding

Manipulation de texte avec grep, sed et awk

Script complet de traitement de fichiers

On combine tout ce qu'on a appris

grep — Rechercher du texte

Filtrer les lignes qui correspondent Ă  un motif

grep "motif" fichier.txt

Cherche dans un fichier

grep -i "motif" fichier.txt

Insensible Ă  la casse

grep -r "motif" dossier/

Récursif

grep -v "motif" fichier.txt

Inverse (exclut)

grep -c "motif" fichier.txt

Compte les occurrences

grep -E "err..r" fichier.txt

Regex étendue

sed — Éditeur de flux

Transformer du texte automatiquement

sed 's/ancien/nouveau/' fichier.txt

Substitution (1re occurrence/ligne)

sed 's/ancien/nouveau/g' fichier.txt

Substitution globale

sed -i 's/ancien/nouveau/g' fichier.txt

Modifier le fichier sur place

sed '/motif/d' fichier.txt

Supprimer les lignes

💡 sed -i .bak 's/foo/bar/g' → crée une sauvegarde .bak avant de modifier

awk — Traitement par colonnes

Parfait pour les fichiers CSV/structurés

awk '{print $1, $3}' data.txt

Affiche colonnes 1 et 3

awk -F, '{print $1}' data.csv

Séparateur = virgule

awk '$3 > 100 {print $0}' data.txt

Filtrer par condition

awk '{sum+=$2} END {print sum}' data.txt

Somme d'une colonne

💡 $0 = toute la ligne, $1 = première colonne, NF = nombre de colonnes

Live Coding : Script complet

#!/bin/bash

# Analyseur de logs — combine tout ce qu'on a appris

logfile="$1"

if [[ $# -ne 1 ]]; then

echo "Usage: $0 <fichier.log>"

exit 1

fi

if [[ ! -f "$logfile" ]]; then

echo "Erreur: fichier introuvable" >&2

exit 2

fi

# Compter les erreurs avec grep

total_erreurs=$(grep -c "ERROR" "$logfile")

echo "Total erreurs: $total_erreurs"

# Extraire les IPs avec sed et awk

grep "ERROR" "$logfile" |

sed 's/.*\[\([0-9.]*\)\].*/\1/' |

sort | uniq -c |

sort -rn | head -5

Points clés à retenir

✅ [[ ]] plutôt que [ ] — plus sûrs et plus puissants

âś… Toujours quoter les variables : "$var"

Évite le word splitting et les bugs avec les espaces

✅ $? = 0 succès, ≠0 erreur — fondamental

✅ return = entier (0-255), echo = stdout → capturé avec $( )

âś… sed pour transformer, awk pour colonnes, grep pour filtrer

⚠️ Pièges courants à éviter

❌ Oublier les espaces dans les tests

[[$x=='y']] # ❌ Erreur

[[ $x == 'y' ]] # âś… Correct

❌ Confondre = et ==

[[ $x = "abc" ]] # ❌ Affectation

[[ $x == "abc" ]] # âś… Comparaison

❌ Ne pas quoter les variables

[[ -f $file ]] # ❌ Bug si espaces

[[ -f "$file" ]] # âś… Robuste

❌ Oublier le shebang

#!/bin/bash en première ligne — toujours !

Récapitulatif

Variables

nom="Alice" • $var • ${var}

export • $? $# $@ $0

Conditions

if [[ condition ]]; then

-eq -ne -lt -f -d -x

Boucles

for • while • until

break • continue

Fonctions

function f { local x=$1; }

return entier • echo texte

Redirections

> >> 2>&1 /dev/null

$(cmd) • pipes |

Outils texte

grep • sed • awk

Filtrer • Transformer • Colonnes

⚠️ N'oubliez pas : quoter les variables, [[ ]], shebang !

Exercices pratiques

1. Script de sauvegarde

Écrire un script qui copie les fichiers .txt dans un dossier backup/ avec horodatage

2. Analyseur de logs

Utiliser grep, sed et awk pour extraire les erreurs d'un fichier log et les compter par type

3. Vérificateur d'arguments

Script qui valide le nombre d'arguments et l'existence du fichier avant de traiter

4. Renommer en masse

Remplacer les espaces par des underscores dans tous les fichiers d'un dossier avec sed

Questions ?

Bash est le couteau suisse du développeur

Scripts, automatisation, manipulation de texte

Vous avez tous les outils pour devenir productifs en ligne de commande