ITSkillsCenter
Blog

Automatiser sa PME avec des scripts Bash : tutoriel pas à pas

9 min de lecture

Ce que vous saurez faire

Ce tutoriel vous apprend a ecrire des scripts Bash pour automatiser les taches repetitives de votre PME senegalaise : sauvegardes quotidiennes, deploiements d’applications, rapports automatises envoyes par email, surveillance de services, et traitement de fichiers en masse. Bash est le shell par defaut sur la plupart des serveurs Linux, ce qui rend vos scripts portables entre machines. Vous apprendrez la syntaxe des variables, conditions, boucles, fonctions, et comment gerer les arguments et codes de retour. A la fin de ce guide, vous pourrez ecrire des scripts robustes pour remplacer les operations manuelles couteuses en temps : par exemple, un script de sauvegarde MySQL automatique avec rotation et upload vers un serveur distant, ou un script de deploiement qui met a jour le code, redemarre les services, et envoie une notification Slack en une seule commande.

Etape 1 : Premier script executable

Un script Bash commence toujours par un shebang #!/bin/bash qui indique au systeme quel interpreteur utiliser. Creez votre premier script avec nano ou vim.

nano hello.sh

Contenu du fichier :

#!/bin/bash
# Mon premier script
echo "Bonjour depuis Dakar"
echo "Date : $(date)"
echo "Utilisateur : $USER"

Rendez-le executable puis lancez-le :

chmod +x hello.sh
./hello.sh
# Bonjour depuis Dakar
# Date : Thu Apr 23 14:30:00 GMT 2026
# Utilisateur : admin

Etape 2 : Variables et substitution

Les variables en Bash n’ont pas de type. Affectation sans espace autour du =, utilisation avec $. Les guillemets doubles autorisent la substitution, les simples non.

#!/bin/bash
nom="Fatou"
age=28
ville="Thies"

echo "Employee : $nom, $age ans, $ville"
echo 'Pas de substitution : $nom'

# Variables systeme utiles
echo "Home : $HOME"
echo "Path : $PATH"
echo "PID courant : $$"

# Substitution de commande
date_aujourdhui=$(date +%Y-%m-%d)
nb_fichiers=$(ls /var/www | wc -l)
echo "Aujourd'hui : $date_aujourdhui, $nb_fichiers fichiers"

Etape 3 : Arguments de ligne de commande

Les scripts recoivent des arguments via $1, $2, etc. $# donne le nombre d’arguments, $@ la liste complete, $0 le nom du script.

#!/bin/bash
# backup.sh - Sauvegarder un dossier

if [ $# -lt 2 ]; then
    echo "Usage : $0 <source> <destination>"
    exit 1
fi

source=$1
destination=$2

echo "Sauvegarde de $source vers $destination"
tar -czf "$destination/backup_$(date +%F).tar.gz" "$source"

echo "Nombre d'arguments recus : $#"
echo "Tous les arguments : $@"

Usage : ./backup.sh /var/www /backups

Etape 4 : Conditions avec if

Les tests utilisent [ ] ou [[ ]]. Respectez les espaces autour des crochets. [[ ]] est plus puissant (regex, comparaison de chaines).

#!/bin/bash
fichier="/etc/nginx/nginx.conf"

if [ -f "$fichier" ]; then
    echo "Le fichier existe"
elif [ -d "$fichier" ]; then
    echo "C'est un dossier"
else
    echo "Introuvable"
fi

# Comparaison de nombres
charge=$(cat /proc/loadavg | awk '{print $1}' | cut -d. -f1)
if [ "$charge" -gt 4 ]; then
    echo "Alerte : charge elevee"
fi

# Comparaison de chaines
env="production"
if [[ "$env" == "production" ]]; then
    echo "Mode prod"
fi

# Tests courants
# -f fichier existe, -d dossier, -e existe
# -r lisible, -w inscriptible, -x executable
# -z vide, -n non vide

Etape 5 : Boucles for et while

Les boucles automatisent les traitements repetes. for itere sur une liste, while continue tant qu’une condition est vraie.

#!/bin/bash

# Boucle sur une liste
for site in site1.sn site2.sn site3.sn; do
    echo "Ping de $site"
    ping -c 1 "$site" > /dev/null && echo "OK" || echo "KO"
done

# Boucle sur des fichiers
for log in /var/log/*.log; do
    taille=$(du -h "$log" | cut -f1)
    echo "$log : $taille"
done

# Boucle numerique
for i in {1..5}; do
    echo "Tentative $i"
done

# While avec compteur
compteur=0
while [ $compteur -lt 3 ]; do
    echo "Iteration $compteur"
    compteur=$((compteur + 1))
done

# Lire un fichier ligne par ligne
while read ligne; do
    echo "Ligne : $ligne"
done < /etc/hostname

Etape 6 : Fonctions reutilisables

Les fonctions organisent le code. Declarez avec function nom() ou nom(), appelez par le nom. Les arguments passent par $1, $2, etc.

#!/bin/bash

log_info() {
    echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}

verifier_service() {
    local service=$1
    if systemctl is-active --quiet "$service"; then
        log_info "$service est actif"
        return 0
    else
        log_error "$service est arrete"
        return 1
    fi
}

# Utilisation
log_info "Debut de la verification"
verifier_service "nginx"
verifier_service "mysql"
log_info "Fin"

Etape 7 : Codes de retour et gestion d’erreurs

Chaque commande retourne un code : 0 = succes, autre = erreur. Utilisez $? pour le recuperer. set -e arrete le script a la premiere erreur, set -u refuse les variables non definies.

#!/bin/bash
set -euo pipefail
# -e : arret sur erreur
# -u : erreur si variable non definie
# -o pipefail : arret si pipe echoue

cp /etc/hosts /tmp/hosts_backup
if [ $? -eq 0 ]; then
    echo "Copie reussie"
else
    echo "Echec de copie"
    exit 1
fi

# Piege de nettoyage automatique
cleanup() {
    echo "Nettoyage en cours"
    rm -f /tmp/verrou.lock
}
trap cleanup EXIT

# Creer un verrou
touch /tmp/verrou.lock
# Travail ...
# cleanup sera appele automatiquement a la sortie

Etape 8 : Case pour choix multiples

Quand vous avez plusieurs conditions sur une meme variable, case est plus lisible qu’une chaine de if/elif.

#!/bin/bash
# deploy.sh env action

env=$1
action=$2

case "$env" in
    dev|development)
        serveur="dev.itskillscenter.io"
        ;;
    staging)
        serveur="staging.itskillscenter.io"
        ;;
    prod|production)
        serveur="itskillscenter.io"
        ;;
    *)
        echo "Environnement inconnu : $env"
        exit 1
        ;;
esac

case "$action" in
    deploy) echo "Deploiement sur $serveur" ;;
    rollback) echo "Rollback sur $serveur" ;;
    status) echo "Statut de $serveur" ;;
    *) echo "Action invalide" ; exit 1 ;;
esac

Etape 9 : Manipulation de chaines

Bash offre des operations natives sur les chaines : longueur, sous-chaine, remplacement, casse.

#!/bin/bash
chaine="Bonjour Dakar Senegal"

# Longueur
echo "${#chaine}"           # 21

# Sous-chaine (position 8, longueur 5)
echo "${chaine:8:5}"        # Dakar

# Remplacement
echo "${chaine/Dakar/Thies}"    # Bonjour Thies Senegal
echo "${chaine//a/@}"       # Bonjour D@k@r Seneg@l

# Casse
echo "${chaine,,}"          # tout en minuscules
echo "${chaine^^}"          # tout en majuscules

# Valeur par defaut
env="${ENV:-development}"   # Si ENV non defini, prend "development"

# Retrait prefixe/suffixe
fichier="rapport_2026_04.csv"
echo "${fichier%.csv}"      # rapport_2026_04
echo "${fichier#*_}"        # 2026_04.csv

Etape 10 : Redirection et pipes

Rediriger la sortie vers un fichier, separer erreurs et sortie standard, chainer des commandes.

#!/bin/bash

# Redirections de base
echo "Sortie standard" > fichier.txt         # Ecrase
echo "Ajout" >> fichier.txt                  # Ajoute
ls fichier_inexistant 2> erreurs.log         # Erreur seulement
ls / 2>&1 > tout.log                         # Les deux vers tout.log

# /dev/null pour silencer
ping -c 1 google.com > /dev/null 2>&1

# Pipe : sortie d'une commande vers entree d'une autre
ps aux | grep nginx | awk '{print $2}' | head -5

# Here-document
cat <<EOF > config.txt
serveur=itskillscenter.io
port=443
ssl=true
EOF

# Here-string
grep "error" <<< "$log_content"

Etape 11 : Script complet de sauvegarde MySQL

Un cas concret : sauvegarder quotidiennement une base MySQL, compresser, faire une rotation sur 7 jours, et envoyer un rapport.

#!/bin/bash
# backup_mysql.sh

set -euo pipefail

# Configuration
DB_USER="backup"
DB_PASS="motdepasse"
DB_NAME="boutique"
BACKUP_DIR="/backups/mysql"
RETENTION_DAYS=7
EMAIL="admin@pme-dakar.sn"

# Creation du dossier si absent
mkdir -p "$BACKUP_DIR"

# Nom du fichier
DATE=$(date +%Y%m%d_%H%M%S)
FICHIER="$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"

# Dump et compression
echo "Sauvegarde de $DB_NAME"
if mysqldump -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$FICHIER"; then
    TAILLE=$(du -h "$FICHIER" | cut -f1)
    echo "Succes : $FICHIER ($TAILLE)"
else
    echo "Echec de sauvegarde" | mail -s "Erreur backup" "$EMAIL"
    exit 1
fi

# Rotation
find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "Nettoyage des sauvegardes > $RETENTION_DAYS jours"

echo "Termine"

Etape 12 : Tableaux (arrays)

Les tableaux stockent plusieurs valeurs. Utilisez () pour declarer, ${array[i]} pour acceder.

#!/bin/bash

# Declaration
serveurs=("srv-web-01" "srv-db-01" "srv-mail-01")

# Acces
echo "${serveurs[0]}"           # Premier element
echo "${serveurs[@]}"           # Tous
echo "${#serveurs[@]}"          # Nombre d'elements

# Ajout
serveurs+=("srv-backup-01")

# Iteration
for srv in "${serveurs[@]}"; do
    if ping -c 1 -W 2 "$srv" > /dev/null 2>&1; then
        echo "$srv : UP"
    else
        echo "$srv : DOWN"
    fi
done

# Tableau associatif (Bash 4+)
declare -A ports
ports[web]=80
ports[ssh]=22
ports[mysql]=3306

for service in "${!ports[@]}"; do
    echo "$service ecoute sur ${ports[$service]}"
done

Etape 13 : Debug et logs

Pour deboguer, activez le mode trace avec set -x. Ajoutez des logs structures pour tracer l’execution en production.

#!/bin/bash
# Script avec debug

LOG_FILE="/var/log/monscript.log"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [$1] $2" | tee -a "$LOG_FILE"
}

# Activer le trace pour une section
set -x
commande_a_debugger
set +x

# Ou au lancement : bash -x monscript.sh

# Exemple complet
log "INFO" "Demarrage du script"
if ! curl -sf "https://itskillscenter.io" > /dev/null; then
    log "ERROR" "Site inaccessible"
    exit 1
fi
log "INFO" "Site OK"

# Verifier la syntaxe sans executer
# bash -n monscript.sh

Etape 14 : Planifier et integrer

Une fois votre script teste, planifiez-le avec cron pour une execution automatique. Stockez-le dans /usr/local/bin pour qu’il soit accessible partout.

# Placer le script
sudo cp backup_mysql.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/backup_mysql.sh
sudo chown root:root /usr/local/bin/backup_mysql.sh

# Editer le crontab
crontab -e

# Ajouter (tous les jours a 2h du matin)
0 2 * * * /usr/local/bin/backup_mysql.sh >> /var/log/backup.log 2>&1

# Verifier
crontab -l

# Tester manuellement
/usr/local/bin/backup_mysql.sh

# Controller les logs
tail -f /var/log/backup.log

Erreurs

Oublier les guillemets autour des variables : sans guillemets, $var est decoupe par les espaces. Si fichier="mon fichier.txt", alors rm $fichier supprime « mon » et « fichier.txt » separement. Toujours utiliser rm "$fichier".

Espaces autour de = : x = 5 est une erreur en Bash. Il faut x=5 sans espaces. Bash interprete x = 5 comme la commande x avec arguments « = » et « 5 ».

Ne pas gerer les erreurs : un script qui continue apres une erreur peut causer des degats. Utilisez set -euo pipefail en haut du script, et verifiez les codes de retour des commandes critiques.

Utiliser sh au lieu de bash : lancer avec sh monscript.sh utilise un shell minimal qui ne comprend pas les tableaux, [[ ]], ou les fonctions avancees. Utilisez toujours bash monscript.sh ou rendez le script executable avec le bon shebang.

Hardcoder les chemins absolus : un script qui contient /home/admin/projet ne marchera pas chez un autre utilisateur. Utilisez $HOME, $(dirname $0), ou des variables de configuration.

Stocker les mots de passe en clair : ne mettez jamais de mots de passe directement dans les scripts. Utilisez des fichiers .env protection 600, ou mieux, des gestionnaires de secrets comme Vault.

Checklist

Shebang #!/bin/bash en premiere ligne.

Script rendu executable avec chmod +x.

set -euo pipefail ajoute pour la robustesse.

Variables entre guillemets doubles pour gerer les espaces.

Arguments valides avant utilisation (verification $#).

Codes de retour verifies avec $? ou if commande.

Fonctions utilisees pour factoriser le code repetitif.

Variables locales dans les fonctions avec local.

Logs horodates ecrits dans un fichier dedie.

Piege trap cleanup EXIT pour nettoyage automatique.

Aucun mot de passe en dur dans le script.

Test de syntaxe avec bash -n script.sh.

Test complet en environnement de dev avant prod.

Planification via cron ou systemd timer.

Rotation des logs configuree (logrotate).

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité