Mini-test 2

Sauvegarde
& fichiers

Dates, archives, tests d'existence, recherche par nom et par contenu, sauvegarde rotative

16 questions + 1 supplement

$(date +...) tar -czf [ -f ] [ -d ] find / grep -r

Cliquez Voir la solution sur chaque slide

← → naviguer · I indice · S solution · R recommencer

Question 1 / 16 tar : c / t / x

Manipuler une archive : creer, lire, extraire

Trois operations classiques avec une archive archives.tgz.
a) Creer archives.tgz a partir de /etc/ircd-hybrid/ :
b) Lister le contenu de archives.tgz sans extraire :
c) Extraire archives.tgz dans le repertoire courant :
man tar. Lettres-cles : -c create, -t tlist (lister), -x extract. Toujours combiner avec -z pour gzip et -f pour le nom de fichier.
TAR(1) - extrait du manuel
NAME
       tar - an archiving utility

SYNOPSIS
       tar [OPERATION] [OPTION...] [FILE...]

OPERATIONS (une seule par commande)
       -c, --create
              creer une nouvelle archive

       -t, --list
              lister le contenu sans extraire

       -x, --extract
              extraire le contenu d'une archive

       -r, --append
              ajouter des fichiers a une archive existante

       -u, --update
              ajouter les fichiers plus recents que ceux deja dans l'archive

OPTIONS DE COMPRESSION
       -z, --gzip
              compression gzip (extension .tgz ou .tar.gz)

       -j, --bzip2
              compression bzip2 (.tbz2)

       -J, --xz
              compression xz (.txz)

       --zstd
              compression zstd (.tar.zst)

AUTRES OPTIONS
       -f FICHIER, --file=FICHIER
              nom de l'archive (TOUJOURS le dernier switch avant le nom)

       -v, --verbose
              afficher chaque fichier traite

       -C DIR, --directory=DIR
              changer de repertoire AVANT d'archiver/extraire
              (utile pour obtenir des chemins relatifs dans l'archive)

       --exclude=PATTERN
              exclure les fichiers qui matchent le pattern

EXEMPLES
       # Creer une archive compressee gzip
       tar -czf archives.tgz /etc/

       # Lister sans extraire
       tar -tzf archives.tgz

       # Extraire dans le repertoire courant
       tar -xzf archives.tgz

       # Creer avec chemins relatifs (option -C)
       tar -czf ircd.tgz -C /var/lib ircd-hybrid/

       # Verifier l'integrite (option avec gzip)
       gzip -t archives.tgz

       # Compter les fichiers dans une archive
       tar -tzf archives.tgz | wc -l
# a) Creer (compresse)
tar -czf archives.tgz /etc/ircd-hybrid/

# b) Lister sans extraire
tar -tzf archives.tgz

# c) Extraire dans le repertoire courant
tar -xzf archives.tgz

Decoupage des switches :

Autres formats : -j pour bzip2 (.tbz2), -J pour xz (.txz), --zstd pour zstd.

Question 2 / 16 la commande date

La date du jour, isolee dans une variable

Avant de combiner avec tar, on prend la commande date toute seule. Vous voulez recuperer la date du jour au format triable (annee-mois-jour) et la stocker dans une variable pour la reutiliser plus loin dans le script.

Donnez :

DATE(1) - extrait du manuel
NAME
       date - afficher ou regler la date du systeme

SYNOPSIS
       date [OPTION...] [+FORMAT]

SPECIFICATEURS DE FORMAT (a preceder de %)
   Date
       %Y     annee sur 4 chiffres                  (2026)
       %m     mois sur 2 chiffres                   (01-12)
       %d     jour du mois sur 2 chiffres           (01-31)
       %j     jour de l'annee                       (001-366)
       %A     nom complet du jour                   (Friday)
       %a     nom abrege du jour                    (Fri)
       %B     nom complet du mois                   (May)
       %u     jour de la semaine (1=lundi)
       %V     numero de semaine ISO 8601
   Heure
       %H     heure 24h                             (00-23)
       %M     minute                                (00-59)
       %S     seconde                               (00-60)
   Speciaux
       %s     timestamp Unix (secondes depuis 1970)
       %Z     fuseau horaire                        (EDT)

OPTIONS UTILES
       -d STRING          afficher une date specifique ("yesterday", "7 days ago")
       -r FICHIER         derniere modification d'un fichier
       -u                 afficher en UTC
       --iso-8601=seconds format ISO 8601 standard

SUBSTITUTION DE COMMANDE (bash)
       $(commande)          syntaxe moderne, recommandee
       `commande`           backticks, historique, deconseille en imbrique

EXEMPLES
       # Afficher
       date +%Y-%m-%d                    # 2026-05-22

       # Capturer dans une variable
       aujourdhui=$(date +%Y-%m-%d)
       echo "${aujourdhui}"               # 2026-05-22

       # Avec heure (plusieurs sauvegardes par jour)
       date +%Y-%m-%d_%H-%M-%S           # 2026-05-22_14-30-05

       # Format compact, sans separateurs
       date +%Y%m%dT%H%M%S               # 20260522T143005

       # Date d'hier
       date -d "yesterday" +%Y-%m-%d

       # Timestamp Unix
       date +%s                          # 1747505405

       # Derniere modif d'un fichier
       date -r /etc/passwd --iso-8601=seconds

REGLE D'OR pour les noms de fichiers : utiliser %Y-%m-%d (ou similaire
avec %Y en premier). Le tri alphabetique correspond alors au tri
chronologique. Eviter %d-%m-%Y qui melange les dates de differentes annees.
# Afficher la date du jour
date +%Y-%m-%d

# Stocker dans une variable (substitution de commande)
aujourdhui=$(date +%Y-%m-%d)
echo "${aujourdhui}"      # affiche 2026-05-22

# Variante backticks (vieux style, equivalent)
aujourdhui=`date +%Y-%m-%d`

Pourquoi %Y-%m-%d en particulier ?

Variantes utiles :

date +%Y-%m-%d_%H-%M-%S          # avec heure
date -d "yesterday" +%Y-%m-%d    # hier
date -d "7 days ago" +%Y-%m-%d   # il y a 7 jours
date +%s                          # timestamp Unix

La question suivante combine cette date avec tar pour nommer une archive.

Question 3 / 16 nommer une archive avec la date

Creer une archive dont le nom contient la date

Vous voulez archiver /var/lib/ircd-hybrid/ dans une archive .tgz dont le nom contient la date du jour (ex. ircd-2026-05-22.tgz).

Donnez les commandes (variable de date + tar) :

DATE(1) - extrait du manuel
NAME
       date - afficher ou regler la date du systeme

SYNOPSIS
       date [OPTION...] [+FORMAT]

SPECIFICATEURS DE FORMAT (a preceder de %)
   Date
       %Y     annee sur 4 chiffres                  (2026)
       %m     mois sur 2 chiffres                   (01-12)
       %d     jour du mois sur 2 chiffres           (01-31)
       %j     jour de l'annee                       (001-366)
       %A     nom complet du jour                   (Friday)
       %a     nom abrege du jour                    (Fri)
       %B     nom complet du mois                   (May)
       %b     nom abrege du mois                    (May)
       %u     jour de la semaine (1=lundi)
       %V     numero de semaine ISO 8601

   Heure
       %H     heure 24h sur 2 chiffres              (00-23)
       %I     heure 12h sur 2 chiffres              (01-12)
       %M     minute sur 2 chiffres                 (00-59)
       %S     seconde sur 2 chiffres                (00-60)

   Speciaux
       %s     timestamp Unix (secondes depuis 1970)
       %N     nanosecondes
       %Z     fuseau horaire                        (EDT)

OPTIONS UTILES
       -d STRING          afficher une date specifique
       -r FICHIER         derniere modification d'un fichier
       -u                 afficher en UTC
       --iso-8601=seconds format ISO 8601 standard

EXEMPLES
       # Date du jour, triable alphabetiquement
       date +%Y-%m-%d                    # 2026-05-22

       # Avec l'heure (pour plusieurs sauvegardes par jour)
       date +%Y-%m-%d_%H-%M-%S           # 2026-05-22_14-30-05

       # Compact, sans separateurs
       date +%Y%m%dT%H%M%S               # 20260522T143005

       # Hier (utile pour archiver "ce qui s'est passe hier")
       date -d "yesterday" +%Y-%m-%d

       # Il y a 7 jours
       date -d "7 days ago" +%Y-%m-%d

       # Timestamp Unix courant
       date +%s                          # 1747505405

       # Convertir un timestamp Unix vers date lisible
       date -d @1747505405

       # Derniere modif d'un fichier en ISO
       date -r /etc/passwd --iso-8601=seconds

REGLE D'OR pour les noms de fichiers : utiliser %Y-%m-%d (ou similaire avec
%Y en premier) - le tri alphabetique correspond alors au tri chronologique.
Eviter %d-%m-%Y qui melange dates de differentes annees a l'affichage.
aujourdhui=$(date +%Y-%m-%d)
sudo tar -czf /var/backups/ircd-${aujourdhui}.tgz /var/lib/ircd-hybrid/

Cles :

Variantes utiles :

# Avec l'heure (utile si plusieurs sauvegardes par jour)
date +%Y-%m-%d_%H-%M-%S

# Format ISO 8601 propre
date +%Y%m%dT%H%M%S

Question 4 / 16 l'option -C de tar

Eviter les chemins absolus dans l'archive

Par defaut, tar -czf archive.tgz /var/lib/ircd-hybrid/ stocke le chemin absolu var/lib/ircd-hybrid/... dans l'archive. A l'extraction, ca peut tout dezipper au mauvais endroit.

Donnez la commande qui :

TAR(1) - extrait du manuel
NAME
       tar - an archiving utility

SYNOPSIS
       tar [OPERATION] [OPTION...] [FILE...]

OPERATIONS (une seule par commande)
       -c, --create
              creer une nouvelle archive

       -t, --list
              lister le contenu sans extraire

       -x, --extract
              extraire le contenu d'une archive

       -r, --append
              ajouter des fichiers a une archive existante

       -u, --update
              ajouter les fichiers plus recents que ceux deja dans l'archive

OPTIONS DE COMPRESSION
       -z, --gzip
              compression gzip (extension .tgz ou .tar.gz)

       -j, --bzip2
              compression bzip2 (.tbz2)

       -J, --xz
              compression xz (.txz)

       --zstd
              compression zstd (.tar.zst)

AUTRES OPTIONS
       -f FICHIER, --file=FICHIER
              nom de l'archive (TOUJOURS le dernier switch avant le nom)

       -v, --verbose
              afficher chaque fichier traite

       -C DIR, --directory=DIR
              changer de repertoire AVANT d'archiver/extraire
              (utile pour obtenir des chemins relatifs dans l'archive)

       --exclude=PATTERN
              exclure les fichiers qui matchent le pattern

EXEMPLES
       # Creer une archive compressee gzip
       tar -czf archives.tgz /etc/

       # Lister sans extraire
       tar -tzf archives.tgz

       # Extraire dans le repertoire courant
       tar -xzf archives.tgz

       # Creer avec chemins relatifs (option -C)
       tar -czf ircd.tgz -C /var/lib ircd-hybrid/

       # Verifier l'integrite (option avec gzip)
       gzip -t archives.tgz

       # Compter les fichiers dans une archive
       tar -tzf archives.tgz | wc -l
sudo tar -czf /var/backups/ircd-$(date +%Y-%m-%d).tgz -C /var/lib ircd-hybrid/

Le secret : -C /chemin dit a tar de "changer de repertoire" avant d'archiver. Ensuite on liste juste le nom relatif (ircd-hybrid/). L'archive contiendra alors les chemins ircd-hybrid/config, ircd-hybrid/data/... au lieu de var/lib/ircd-hybrid/...

Comparaison du contenu :

# Avec chemins absolus (par defaut)
tar -tzf archive.tgz
> var/lib/ircd-hybrid/config
> var/lib/ircd-hybrid/data

# Avec -C
tar -tzf archive.tgz
> ircd-hybrid/config
> ircd-hybrid/data

Astuce : avant de creer l'archive, faire tar -tzf archive.tgz | head sur une vieille pour verifier ce qu'elle contient.

Question 5 / 16 idempotence : mkdir -p

Creer le repertoire de destination... s'il n'existe pas

Le repertoire /var/backups/ircd/ n'existe peut-etre pas la premiere fois. Mais a la deuxieme execution, il existera. Le script ne doit pas planter dans aucun des deux cas.

Donnez la commande qui cree le repertoire sans erreur s'il existe deja, et explique l'option clef :

MKDIR(1) - extrait du manuel
NAME
       mkdir - creer des repertoires

SYNOPSIS
       mkdir [OPTIONS] REPERTOIRE...

OPTIONS
       -p, --parents      cle pour l'idempotence : cree les parents
                         intermediaires et ne pas erreur si la cible existe deja
       -m, --mode MODE    permissions a appliquer        (defaut 0755)
       -v, --verbose      afficher chaque repertoire cree
       -Z                 contexte SELinux par defaut

EXEMPLES
       # Idempotent : marche que /var/backups/ircd existe ou pas
       sudo mkdir -p /var/backups/ircd

       # Avec permissions specifiques (lisible par proprio uniquement)
       mkdir -m 0700 ~/.secrets

       # Plusieurs niveaux d'un coup (expansion bash)
       mkdir -p /opt/monapp/{bin,etc,lib,logs}

       # Sans -p, echec a la 2e execution :
       mkdir /var/backups/ircd
       mkdir: cannot create directory '/var/backups/ircd': File exists

VOIR AUSSI
       rmdir     supprime un repertoire VIDE (sinon utiliser rm -rf, avec prudence)
       touch     creer un fichier vide (idempotent par nature)
       install -d  variante de mkdir avec gestion fine des permissions/proprio

PATRONS IDEMPOTENTS classiques (commandes qui ne plantent pas si deja fait) :
       mkdir -p REP          repertoire (et parents)
       touch FICHIER         fichier vide (ou mise a jour de la date)
       ln -sf src dst        recreer un lien symbolique
       useradd ... || true   creer un user en ignorant l'erreur "deja existant"
sudo mkdir -p /var/backups/ircd

L'option -p fait 2 choses :

C'est la commande idempotente type. Sans -p, on aurait :

mkdir /var/backups/ircd
mkdir: cannot create directory '/var/backups/ircd': File exists  # echec a la 2e execution

D'autres patterns idempotents pour la creation :

touch /var/log/audit.log         # ne plante pas si existe
ln -sf source destination         # remplace le lien existant
useradd -f 0 ... ou id -u user || useradd ...  # n'echoue pas si user existe

Question 6 / 16 $(date +...) dans un nom

Nommer une sauvegarde du jour

Vous voulez creer une archive backup-AAAA-MM-JJ.tgz (ex. backup-2026-05-13.tgz) du repertoire /var/lib/ircd-hybrid/.
a) Commande complete avec la date du jour :
b) Avec heure et minute (ex. backup-2026-05-13_14-30.tgz) :
man date. Format : %Y annee, %m mois, %d jour, %H heure, %M minute. La substitution de commande : $(date +%Y-%m-%d).
DATE(1) - extrait du manuel
SPECIFICATEURS DE FORMAT (a preceder de %)
       %Y     annee 4 chiffres                       (2026)
       %m     mois  2 chiffres                       (01-12)
       %d     jour  2 chiffres                       (01-31)
       %H     heure 24h                              (00-23)
       %M     minute                                 (00-59)
       %S     seconde                                (00-60)
       %s     timestamp Unix (secondes depuis 1970)
       %j     jour de l'annee                        (001-366)
       %A     nom complet du jour                    (Friday)
       %B     nom complet du mois                    (May)

OPTIONS
       -d "STRING"   afficher une date specifique ("yesterday", "7 days ago")
       -r FICHIER    date de derniere modif d'un fichier
       --iso-8601=seconds  format ISO 8601 standard

SUBSTITUTION
       $(commande)      capture la sortie comme valeur (syntaxe moderne)

EXEMPLES
       date +%Y-%m-%d                    # 2026-05-22 (triable)
       date +%Y-%m-%d_%H-%M-%S           # avec heure et minute
       date +%Y%m%dT%H%M%S               # compact, ISO 8601
       date -d "yesterday" +%Y-%m-%d
       date -d "7 days ago" +%Y-%m-%d
       date +%s                          # 1747505405

REGLE D'OR : %Y-%m-%d (annee en premier) - le tri alphabetique = tri chronologique.
TAR(1) - extrait du manuel
NAME
       tar - an archiving utility

SYNOPSIS
       tar [OPERATION] [OPTION...] [FICHIER...]

OPERATIONS (une par commande)
       -c, --create          creer une archive
       -t, --list            lister sans extraire
       -x, --extract         extraire
       -r, --append          ajouter a une archive existante
       -u, --update          ajouter seulement les fichiers plus recents

COMPRESSION
       -z, --gzip            gzip   (extension .tgz / .tar.gz)
       -j, --bzip2           bzip2  (.tbz2)
       -J, --xz              xz     (.txz)

OPTIONS frequentes
       -f NOM                nom du fichier d'archive (TOUJOURS necessaire)
       -v                    verbeux (afficher chaque fichier traite)
       -C DIR                changer de repertoire avant l'archivage
                              (utile pour stocker un chemin RELATIF dans l'archive)
       --exclude=PATTERN     exclure des fichiers (peut etre repete)
       -p, --preserve-permissions  conserver les permissions

EXEMPLES (focus archivage avec date)
       # Archive datee
       tar -czf backup-$(date +%Y-%m-%d).tgz /var/lib/ircd-hybrid/

       # Avec heure (plusieurs par jour)
       tar -czf backup-$(date +%Y-%m-%d_%H-%M).tgz /var/lib/ircd-hybrid/

       # Lister le contenu (verification)
       tar -tzf backup-2026-05-22.tgz | head -20

       # Extraire (dans le repertoire courant)
       tar -xzf backup-2026-05-22.tgz

       # Eviter le chemin absolu dans l'archive (-C)
       tar -czf backup.tgz -C /var/lib ircd-hybrid/
       # L'archive contient ircd-hybrid/foo plutot que /var/lib/ircd-hybrid/foo

       # Avec exclusion
       tar -czf backup.tgz --exclude='*.log' /var/lib/ircd-hybrid/

MEMO MNEMONIQUE : "Cooked Zucchini Filet" pour -czf (create + gzip + file)
# a) Date du jour AAAA-MM-JJ (tri naturel)
tar -czf backup-$(date +%Y-%m-%d).tgz /var/lib/ircd-hybrid/

# b) Avec heure (utile si plusieurs sauvegardes par jour)
tar -czf backup-$(date +%Y-%m-%d_%H-%M).tgz /var/lib/ircd-hybrid/

Pourquoi %Y-%m-%d ? Le tri alphabetique correspond au tri chronologique. Eviter %d-%m-%Y qui trie mal (les 01-* viennent avant les annees).

Variantes utiles :

date +%Y%m%dT%H%M%S    # format ISO 8601 propre
date +%s              # timestamp Unix (secondes depuis 1970)
date '+%d %B %Y'      # "13 May 2026" lisible humain

Question 7 / 16 [ -f ] et [ -d ]

Le fichier (ou le repertoire) existe-t-il ?

Avant d'agir, on verifie ce qui est deja la.
a) Si /etc/ircd-hybrid/ircd.conf n'existe pas, le copier depuis le modele /etc/ircd-hybrid/ircd.conf.default :
b) Si le repertoire /var/log/ircd-hybrid n'existe pas, le creer (avec parents) :
man test ou man bash section CONDITIONAL EXPRESSIONS. -f = fichier ordinaire, -d = repertoire, -e = n'importe quoi. Pour la negation : ! -f ou [ ! -f ... ].
TEST(1) / [ ] - extrait du manuel
NAME
       test, [ - evaluer une expression conditionnelle

SYNOPSIS
       test EXPRESSION
       [ EXPRESSION ]

       Equivalents : test -f /etc/passwd  ==  [ -f /etc/passwd ]
       (le [ est une commande, pas de la syntaxe : besoin d'espaces partout !)

TESTS DE FICHIER
       -e FICHIER      existe (n'importe quel type)
       -f FICHIER      existe ET est un fichier ordinaire
       -d FICHIER      existe ET est un repertoire
       -L FICHIER      existe ET est un lien symbolique
       -s FICHIER      existe ET de taille non-nulle
       -r FICHIER      lisible par moi
       -w FICHIER      ecrivable par moi
       -x FICHIER      executable par moi
       F1 -nt F2       F1 plus recent (newer than) que F2
       F1 -ot F2       F1 plus ancien (older than) que F2

TESTS DE CHAINES
       -z CHAINE       chaine vide
       -n CHAINE       chaine non vide
       CH1 = CH2       chaines egales      (PAS == dans [ ], = uniquement)
       CH1 != CH2      chaines differentes

TESTS NUMERIQUES
       N1 -eq N2       egaux
       N1 -ne N2       differents
       N1 -lt N2       N1 < N2
       N1 -le N2       N1 <= N2
       N1 -gt N2       N1 > N2
       N1 -ge N2       N1 >= N2

COMBINAISON
       ! EXPR          negation
       E1 -a E2        ET (dans [ ])
       E1 -o E2        OU (dans [ ])

       Preferable en pratique : enchainer avec && et || du shell :
            [ -f X ] && [ -d Y ]      # ET
            [ -f X ] || [ -f Z ]      # OU

VARIANTE BASH [[ ... ]]
       Operateur double-crochet de bash, plus permissif :
       - pas besoin d'echapper les regex
       - == et != autorisent les globs
       - regex avec =~      [[ "$f" =~ \.tgz$ ]]
       - PAS portable vers /bin/sh

EXEMPLES (idempotence)
       # Si le fichier de config est absent, le creer depuis un modele
       [ -f /etc/foo.conf ] || cp /etc/foo.conf.default /etc/foo.conf

       # Si le repertoire de log n'existe pas, le creer
       [ -d /var/log/myapp ] || mkdir -p /var/log/myapp

       # Sortir si fichier obligatoire absent
       [ -f /etc/myapp.conf ] || { echo "config manquante"; exit 1; }

       # Bloc if classique
       if [ ! -f /etc/myapp.conf ]; then
           echo "config manquante"
           exit 1
       fi

PIEGE : LES ESPACES
       [ -f /etc/foo ]      # OK
       [-f /etc/foo]        # KO (manque les espaces autour de [ et ])
       [ -f /etc/foo]       # KO aussi
       [ -f $VAR ]          # OK mais quoter pour les noms a espaces : [ -f "$VAR" ]
# a) Fichier de config manquant : restaurer depuis le modele
[ -f /etc/ircd-hybrid/ircd.conf ]     || cp /etc/ircd-hybrid/ircd.conf.default /etc/ircd-hybrid/ircd.conf

# b) Repertoire de log a creer si absent
[ -d /var/log/ircd-hybrid ] || mkdir -p /var/log/ircd-hybrid

Cles a connaitre :

Variante moderne avec [[ ]] :

if [[ ! -f /etc/ircd-hybrid/ircd.conf ]]; then
    cp /etc/ircd-hybrid/ircd.conf.default /etc/ircd-hybrid/ircd.conf
fi

Question 8 / 16 premier assemblage

Assembler un mini-script de sauvegarde

On a vu : la commande date, tar, l'option -C, mkdir -p, et les tests [ -f ] / [ -d ]. On combine ces 5 briques dans un premier script simple. La rotation, le grep et la verification arrivent dans les questions suivantes.

Ecrivez le script mini-sauvegarde.sh qui :

  1. stocke la date du jour (format %Y-%m-%d) dans une variable aujourdhui
  2. cree le repertoire /var/backups/ircd s'il n'existe pas (idempotent)
  3. verifie que la source /var/lib/ircd-hybrid existe ; sinon affiche un message et sort avec code 1
  4. archive la source dans /var/backups/ircd/ircd-AAAA-MM-JJ.tgz avec chemin relatif (utilise -C)
  5. affiche un message OK : nom de l'archive a la fin
#!/bin/bash
# mini-sauvegarde.sh - assemblage intermediaire
set -e

# 1. Date du jour
aujourdhui=$(date +%Y-%m-%d)

# 2. Repertoire de destination (idempotent)
sudo mkdir -p /var/backups/ircd

# 3. Verification de la source
if [ ! -d /var/lib/ircd-hybrid ]; then
    echo "ERREUR : /var/lib/ircd-hybrid n'existe pas" >&2
    exit 1
fi

# 4. Archive avec chemin relatif (le -C change de repertoire avant)
nom_archive="ircd-${aujourdhui}.tgz"
sudo tar -czf "/var/backups/ircd/${nom_archive}" \
    -C /var/lib ircd-hybrid

# 5. Message final
echo "OK : /var/backups/ircd/${nom_archive}"

Decomposition :

Ce qu'on n'a PAS encore fait (et qui vient apres) :

Question 9 / 16 find : par nom

Trouver un fichier par son NOM

Chercher des fichiers selon des criteres sur leur nom et leur age.
a) Tous les fichiers .conf quelque part sous /etc/ :
b) Les .log dans /var/log/ modifies dans les 7 derniers jours :
man find. Format : find ou-chercher -critere1 -critere2 .... -name = nom (utiliser les guillemets si jokers), -mtime = age (en jours ; -N = moins de N jours, +N = plus de N jours).
FIND(1) - extrait du manuel
NAME
       find - search for files in a directory hierarchy

SYNOPSIS
       find [STARTING-POINT...] [EXPRESSION]

DESCRIPTION
       find searches the directory tree rooted at each STARTING-POINT
       and evaluates the EXPRESSION on each file.

EXPRESSIONS

   Tests (selection des fichiers) :
       -name PATTERN       nom matche le pattern (utiliser guillemets!)
       -iname PATTERN      idem, insensible a la casse
       -type [fdl]         f=fichier, d=repertoire, l=symlink
       -size [+-]N[c|k|M|G]   taille du fichier
       -mtime [+-]N        modifie il y a N jours
                           # +N : plus de N jours (vieux)
                           # -N : moins de N jours (recent)
       -newer FILE         modifie plus recemment que FILE
       -user USER          appartient a USER
       -perm MODE          permissions

   Actions (que faire avec les fichiers trouves) :
       -print              affiche le chemin (par defaut)
       -delete             supprime le fichier
       -exec CMD {} \;     execute CMD une fois par fichier
       -exec CMD {} +      execute CMD une fois pour plusieurs fichiers (plus rapide)
       -ls                 ls -dils pour chaque fichier trouve

EXEMPLES
       # Tous les .conf dans /etc
       find /etc -name "*.conf"

       # .log modifies dans les 7 derniers jours
       find /var/log -name "*.log" -mtime -7

       # Fichiers de plus de 10 Mo
       find . -type f -size +10M

       # Supprimer fichiers tmp plus vieux que 30 jours
       find /tmp -mtime +30 -delete

       # Combiner find + grep (chercher du contenu dans certains fichiers)
       find /etc -name "*.conf" -exec grep -l "ssl" {} +
# a) Tous les .conf dans /etc (recursif par defaut)
find /etc -name "*.conf"

# b) Les .log modifies dans les 7 derniers jours
find /var/log -name "*.log" -mtime -7

Autres criteres utiles :

Actions a la fin : -print (defaut), -delete, -exec cmd {} +.

Question 10 / 16 rotation : effacer les vieilles

Supprimer les archives de plus de N jours

Sans rotation, le disque se remplit. On veut garder 14 jours d'archives .tgz dans /var/backups/ircd/ et effacer le reste.

Donnez la commande find qui supprime les fichiers .tgz de plus de 14 jours :

FIND(1) - extrait du manuel
NAME
       find - search for files in a directory hierarchy

SYNOPSIS
       find [STARTING-POINT...] [EXPRESSION]

EXPRESSIONS

   Tests (selection des fichiers) :
       -name PATTERN       nom matche le pattern (utiliser guillemets!)
       -iname PATTERN      idem, insensible a la casse
       -type [fdl]         f=fichier, d=repertoire, l=symlink
       -size [+-]N[c|k|M|G]   taille du fichier
       -mtime [+-]N        modifie il y a N jours
                           # +N : plus de N jours (vieux)
                           # -N : moins de N jours (recent)
       -newer FILE         modifie plus recemment que FILE
       -user USER          appartient a USER

   Actions :
       -print              affiche le chemin (par defaut)
       -delete             supprime le fichier
       -exec CMD {} \;     execute CMD pour chaque fichier
       -exec CMD {} +      execute CMD pour plusieurs fichiers (plus rapide)

EXEMPLES
       find /etc -name "*.conf"
       find /var/log -name "*.log" -mtime -7
       find . -type f -size +10M
       find /tmp -mtime +30 -delete
       find /etc -name "*.conf" -exec grep -l "ssl" {} +
find /var/backups/ircd/ -name "*.tgz" -type f -mtime +14 -delete

Decomposition :

Piege classique : -mtime se base sur le mtime du fichier, pas son nom. Si quelqu'un a fait touch sur une vieille archive, elle ne sera pas effacee meme si son nom contient une date ancienne.

Reflexes avant -delete :

# 1. Lister d'abord pour verifier ce qui va etre efface
find /var/backups/ircd/ -name "*.tgz" -type f -mtime +14

# 2. Ou utiliser -print pour confirmer
find /var/backups/ircd/ -name "*.tgz" -type f -mtime +14 -print -delete

Section

Fichiers
& recherche

Trouver des fichiers par nom, par age, par contenu

5 questions

grep -r find + grep wc / head / tail tout assembler

Combiner les outils trouver, filtrer, compter

Question 11 / 16 grep : par contenu

Trouver un fichier par son CONTENU

Cette fois on ne sait pas dans quel fichier, mais on sait ce qu'on cherche a l'interieur.
a) Chercher recursivement la chaine port 6667 dans tous les fichiers de /etc/ircd-hybrid/ :
b) Lister uniquement les NOMS de fichiers qui contiennent ce motif (pas les lignes elles-memes) :
man grep. -r recursif (descend dans les sous-repertoires), -l liste seulement les NOMS de fichiers correspondants, -i insensible a la casse, -n affiche les numeros de ligne.
GREP(1) - extrait du manuel
NAME
       grep - chercher des motifs dans des fichiers

SYNOPSIS
       grep [OPTIONS] MOTIF [FICHIER...]

OPTIONS frequentes (parcours)
       -r, --recursive          descendre dans les sous-repertoires
       -R, --dereference-recursive  recursif + suivre les liens symboliques
       -l, --files-with-matches  afficher seulement les NOMS de fichiers
       -L, --files-without-match noms de fichiers SANS le motif

OPTIONS frequentes (presentation)
       -n, --line-number        numero de ligne de chaque match
       -c, --count              compter les occurrences par fichier
       -H                       afficher le nom du fichier (defaut si plus d'un fichier)
       -A NUM                   afficher NUM lignes APRES le match
       -B NUM                   afficher NUM lignes AVANT le match
       -C NUM                   contexte : NUM lignes avant ET apres
       --color=auto             colorer les matches

OPTIONS frequentes (motif)
       -i, --ignore-case        insensible a la casse
       -v, --invert-match       lignes qui NE matchent PAS
       -w, --word-regexp        match de mot complet (entoure de \b)
       -x, --line-regexp        match la ligne entiere
       -F, --fixed-strings      motif litteral (pas de regex)
       -E, --extended-regexp    regex etendues (+ ? | () sans backslash)
       -q, --quiet              aucune sortie, juste le code de retour

CODES DE SORTIE (utiles dans un script)
       0     au moins un match
       1     aucun match
       2     erreur

EXEMPLES
       # Chercher dans un seul fichier
       grep "port 6667" /etc/ircd-hybrid/ircd.conf

       # Recursif : descendre dans tous les sous-dossiers
       grep -r "port 6667" /etc/ircd-hybrid/

       # Seulement les noms de fichiers qui contiennent (utile avec beaucoup de hits)
       grep -rl "port 6667" /etc/ircd-hybrid/

       # Avec contexte (3 lignes avant + apres chaque match)
       grep -rn -C 3 "port 6667" /etc/ircd-hybrid/

       # Compter par fichier
       grep -rc "ERROR" /var/log/

       # Inverser : lignes SANS le motif (ex : enlever les commentaires)
       grep -v "^#" /etc/apache2/apache2.conf

       # Idempotent : tester si un motif est present
       if grep -qF "[ircd-hybrid]" /etc/fail2ban/jail.local; then ... ; fi

EXCLUSIONS courantes (rgrep / grep -r)
       --include='*.conf'      restreindre aux *.conf
       --exclude='*.bak'       sauter les *.bak
       --exclude-dir='.git'    sauter les sous-dossiers .git
# a) Recherche recursive du motif
grep -r "port 6667" /etc/ircd-hybrid/

# b) Seulement les noms de fichiers qui matchent
grep -rl "port 6667" /etc/ircd-hybrid/
# Equivalent (l et r dans n'importe quel ordre)
grep -l -r "port 6667" /etc/ircd-hybrid/

Options frequentes de grep :

Question 12 / 16 find + grep

Chercher un motif dans certains types de fichiers

Le besoin classique : "trouver tous les fichiers d'un certain type qui contiennent un certain motif".

Listez tous les fichiers .conf sous /etc/ qui contiennent enable_ssl=yes. Une seule commande, en chainant find et grep :

L'option -exec de find lance une commande pour chaque fichier trouve. Le symbole {} represente le fichier courant. Terminer par \; (une commande par fichier) ou + (commande groupee, plus efficace). Alternative : grep -r --include="*.conf".
FIND(1) - extrait du manuel
NAME
       find - search for files in a directory hierarchy

SYNOPSIS
       find [STARTING-POINT...] [EXPRESSION]

EXPRESSIONS

   Tests (selection des fichiers) :
       -name PATTERN       nom matche le pattern (utiliser guillemets!)
       -iname PATTERN      idem, insensible a la casse
       -type [fdl]         f=fichier, d=repertoire, l=symlink
       -size [+-]N[c|k|M|G]   taille du fichier
       -mtime [+-]N        modifie il y a N jours
                           # +N : plus de N jours (vieux)
                           # -N : moins de N jours (recent)
       -newer FILE         modifie plus recemment que FILE
       -user USER          appartient a USER

   Actions :
       -print              affiche le chemin (par defaut)
       -delete             supprime le fichier
       -exec CMD {} \;     execute CMD pour chaque fichier
       -exec CMD {} +      execute CMD pour plusieurs fichiers (plus rapide)

EXEMPLES
       find /etc -name "*.conf"
       find /var/log -name "*.log" -mtime -7
       find . -type f -size +10M
       find /tmp -mtime +30 -delete
       find /etc -name "*.conf" -exec grep -l "ssl" {} +
# Methode classique : find -exec grep
find /etc -name "*.conf" -exec grep -l "enable_ssl=yes" {} +

# Variante avec --include de grep (plus simple a retenir)
grep -rl --include="*.conf" "enable_ssl=yes" /etc/

# Variante avec xargs (utile si on veut piper a autre chose ensuite)
find /etc -name "*.conf" | xargs grep -l "enable_ssl=yes"

Les 3 variantes valent mieux que l'autre ?

Difference {} \; vs {} + :

find . -name "*.txt" -exec grep "foo" {} \;   # 1 grep PAR fichier (lent)
find . -name "*.txt" -exec grep "foo" {} +    # 1 grep avec PLUSIEURS fichiers (rapide)

Question 13 / 16 compter (wc)

Compter avec wc

wc (word count) compte non seulement les mots, mais aussi lignes, caracteres, octets... selon les options.
a) Compter le nombre de lignes de /var/log/auth.log :
b) Compter le nombre de mots dans /etc/motd :
c) Connaitre la taille en octets de /etc/passwd :
d) Trouver la longueur de la ligne la plus longue de /etc/services :
WC(1) - extrait du manuel
NAME
       wc - afficher le nombre de lignes, mots et octets d'un fichier

SYNOPSIS
       wc [OPTIONS] [FICHIER...]

OPTIONS (combinables)
       -l, --lines         compter les lignes (newlines)
       -w, --words         compter les mots (separes par whitespace)
       -c, --bytes         compter les octets
       -m, --chars         compter les caracteres (Unicode-aware, peut differer de -c)
       -L, --max-line-length  longueur de la ligne la PLUS LONGUE
       -w -l -c          combiner : sortie sur une ligne par fichier

SORTIE PAR DEFAUT (sans option)
       lignes  mots  octets  nom-du-fichier
       Equivaut a wc -lwc

ENTREE STANDARD (pipe)
       # wc lit stdin si pas de fichier - tres pratique en pipe
       cat /etc/passwd | wc -l
       grep ERROR /var/log/syslog | wc -l        # compte les erreurs
       ls /etc | wc -l                            # compte les entrees de /etc

EXEMPLES
       # Lignes d'un fichier
       wc -l /var/log/auth.log

       # Mots dans un fichier texte
       wc -w discours.txt

       # Octets (taille fichier sans metadata)
       wc -c image.jpg
       # Equivalent (mais avec metadata) :
       stat -c %s image.jpg

       # Caracteres (Unicode)
       echo "cafe" | wc -m     # 5 (4 caracteres + newline)
       echo "cafe" | wc -c     # 6 (5 octets car "e" est 2 octets en UTF-8) + newline = ah non,
                               # en fait UTF-8 "e" = 2 octets, donc cafe = 5 octets + newline = 6

       # Ligne la plus longue (pour reperer les lignes trop larges)
       wc -L /etc/services

       # Plusieurs fichiers : un total est ajoute
       wc -l /var/log/*.log

USAGE TYPIQUE EN PIPE
       cmd | wc -l            compter les sorties d'une commande (super utile)

       # Combien d'utilisateurs ?
       wc -l /etc/passwd

       # Combien de processus actifs ?
       ps -e | wc -l

       # Combien de fichiers .conf dans /etc ?
       find /etc -name '*.conf' | wc -l
# a) Lignes
wc -l /var/log/auth.log

# b) Mots
wc -w /etc/motd

# c) Octets
wc -c /etc/passwd

# d) Longueur de la ligne la plus longue
wc -L /etc/services

Sans option, wc fichier affiche les 3 premiers (lignes / mots / octets) sur une seule ligne.

Pattern le plus utilise dans la vraie vie : commande | wc -l pour compter les sorties.

Supplement

Aller plus loin

Non evalue a l'examen mais utile a connaitre

Bits speciaux

sticky bit suid / guid

Supplement bits speciaux (non evalue)

Sticky bit, suid, guid

En plus des permissions classiques (rwx pour user/group/other), Linux a 3 bits speciaux qui modifient le comportement d'execution ou de creation de fichiers.
a) Activer le sticky bit sur /tmp (octal et symbolique) :
b) Activer le suid sur un binaire /usr/local/bin/mon-outil (utile pour qu'il tourne en tant que owner) :
c) Activer le guid sur un repertoire (pour que les fichiers crees heritent du groupe) :
Octal : sticky=1, suid=4, guid=2, ces chiffres viennent en PREFIXE des permissions usuelles. Symbolique : +t sticky, u+s suid, g+s guid.
CHMOD(1) - extrait du manuel
NAME
       chmod - modifier les permissions d'un fichier ou repertoire

SYNOPSIS
       chmod [OPTIONS] MODE FICHIER...

MODE - notation OCTALE (4 chiffres : speciaux + user + group + other)
       chiffre 1 (gauche) : bits speciaux (optionnel)
            1xxx     sticky bit (t)        seul le proprietaire efface ses fichiers
            2xxx     guid bit (s sur group) repertoires : fichiers heritent du groupe
            4xxx     suid bit (s sur user) executables : tourne avec uid du proprietaire
            7xxx     les 3 ensemble

       Chiffres user/group/other :
            4 = r   (lecture)
            2 = w   (ecriture)
            1 = x   (execution OU traverser un repertoire)
            0 = aucun

       Exemples : 755 = rwxr-xr-x, 644 = rw-r--r--, 700 = rwx------

MODE - notation SYMBOLIQUE
       u=user (proprietaire), g=group, o=other, a=all
       +=ajouter, -=enlever, ==fixer exactement
       r=read, w=write, x=execute
       t=sticky, s=suid (u+s) ou guid (g+s)

       chmod u+x fichier     # ajouter execute pour user
       chmod go-w fichier    # enlever write pour group et other
       chmod a=r fichier     # tout le monde : read seul
       chmod +x fichier      # raccourci pour ugo+x

OPTIONS
       -R, --recursive      appliquer recursivement
       --reference=FICHIER  copier les permissions d'un autre fichier
       -v                   verbeux

BITS SPECIAUX en detail
       STICKY bit (1, ou +t)
            Sur un repertoire : seul le PROPRIETAIRE d'un fichier peut l'effacer,
            meme si tout le monde a w sur le repertoire.
            Usage type : /tmp (drwxrwxrwt)

       SUID bit (4, ou u+s)
            Sur un executable : il tourne avec l'uid du PROPRIETAIRE du binaire,
            pas avec l'uid de celui qui le lance.
            Usage type : /usr/bin/passwd (modifie /etc/shadow en root)
            RISQUE : suid + bug = escalade de privileges.

       GUID bit (2, ou g+s)
            Sur un executable : tourne avec le gid du group.
            Sur un repertoire : les fichiers crees a l'interieur heritent du
            group du repertoire (utile pour les dossiers d'equipe).

EXEMPLES
       # Sticky bit sur /tmp
       chmod 1777 /tmp                  # octal
       chmod +t /tmp                    # symbolique

       # Suid sur un binaire (s'execute en tant que owner)
       chmod 4755 /usr/local/bin/mon-outil
       chmod u+s /usr/local/bin/mon-outil

       # Guid sur un repertoire d'equipe
       chmod 2775 /var/partage-equipe
       chmod g+s /var/partage-equipe

       # Permissions classiques
       chmod 755 script.sh              # executable pour tous
       chmod 600 ~/.ssh/id_rsa          # cle privee : owner only
       chmod 644 fichier.txt            # standard fichier
       chmod -R 755 mon-projet/         # recursif

AUDIT
       # Trouver tous les binaires SUID (audit securite)
       sudo find / -perm -4000 -type f 2>/dev/null

       # Idem GUID
       sudo find / -perm -2000 -type f 2>/dev/null

       # Tous les fichiers world-writable (risque)
       sudo find / -perm -o+w -type f 2>/dev/null

LIRE les permissions
       ls -l affiche : -rwxr-xr-x
       Position 1 : type (-, d, l, c, b, p, s)
       Positions 2-4 : user (rwx)
       Positions 5-7 : group (rwx)
       Positions 8-10 : other (rwx)

       Avec bits speciaux :
       drwxrwxrwt  sticky    (t a la place du x other)
       -rwsr-xr-x  suid      (s a la place du x user)
       -rwxr-sr-x  guid      (s a la place du x group)
# a) Sticky bit (1) sur /tmp : seul le proprietaire peut effacer ses fichiers
sudo chmod 1777 /tmp
# Equivalent symbolique :
sudo chmod +t /tmp

# b) Suid (4) sur un binaire : il s'execute toujours en tant que owner
sudo chmod 4755 /usr/local/bin/mon-outil
sudo chmod u+s /usr/local/bin/mon-outil

# c) Guid (2) sur un repertoire : nouveaux fichiers heritent du groupe
sudo chmod 2775 /var/partage
sudo chmod g+s /var/partage

Visualiser les bits speciaux dans ls -l :

Utilisations classiques :

Attention : suid est un risque de securite si mal utilise. Toujours auditer avec find / -perm -4000 -type f.

Question 14 / 16 previsualiser (head, tail)

Voir le debut, la fin, et suivre en direct

head et tail sont les outils pour regarder rapidement les premieres ou les dernieres lignes d'un fichier - tres utile pour les gros logs.
a) Voir les 5 premieres lignes de /etc/passwd :
b) Voir les 20 dernieres lignes de /var/log/syslog :
c) Suivre en temps reel les nouvelles lignes de /var/log/syslog :
HEAD(1) - extrait du manuel
NAME
       head - afficher la PREMIERE partie d'un fichier (10 lignes par defaut)

SYNOPSIS
       head [OPTIONS] [FICHIER...]

OPTIONS
       -n N             afficher les N premieres lignes (defaut : 10)
       -N               raccourci pour -n N     (ex: head -5 fichier)
       -n -N            tout SAUF les N dernieres lignes  (note le moins)
       -c N             les N premiers octets
       -q               quiet : ne pas mettre l'entete avec le nom de fichier
                        (utile quand plusieurs fichiers)
       -v               verbeux : forcer l'entete meme si un seul fichier

EXEMPLES
       head -n 5 /etc/passwd      # 5 premieres lignes
       head -5 /etc/passwd        # equivalent (raccourci)
       head /etc/passwd           # 10 premieres lignes (defaut)
       head -n -10 /etc/passwd    # tout SAUF les 10 dernieres lignes
       head -c 100 fichier.bin    # 100 premiers octets (binaire OK)

       # Combine avec un pipe pour regarder le debut d'une commande verbose
       ps -e | head -20

       # Plusieurs fichiers : entete par fichier
       head -3 /var/log/*.log
TAIL(1) - extrait du manuel
NAME
       tail - afficher la DERNIERE partie d'un fichier (10 lignes par defaut)

SYNOPSIS
       tail [OPTIONS] [FICHIER...]

OPTIONS
       -n N             afficher les N dernieres lignes (defaut : 10)
       -N               raccourci pour -n N     (ex: tail -20 fichier)
       -n +N            a partir de la ligne N (la +N inclus)
       -c N             les N derniers octets
       -f, --follow     suivre en temps reel les ajouts au fichier
       -F               idem -f mais resiste a la rotation (logrotate)
                        (ferme et rouvre le fichier au besoin)
       -s N             avec -f, attendre N secondes entre les checks (defaut 1.0)
       --pid=PID        avec -f, arreter quand le process PID se termine

EXEMPLES
       tail -n 20 /var/log/syslog       # 20 dernieres lignes
       tail -20 /var/log/syslog         # equivalent
       tail -f /var/log/syslog          # suivre en temps reel
       tail -F /var/log/syslog          # mieux : resiste a logrotate
       tail -n +100 fichier             # a partir de la ligne 100

       # Suivre PLUSIEURS logs en parallele (etiquetes par nom de fichier)
       tail -f /var/log/syslog /var/log/auth.log

       # Combine head + tail pour extraire un milieu
       head -n 110 fichier | tail -n 10    # lignes 101 a 110

       # Variante moderne : sed (peut faire pareil)
       sed -n '101,110p' fichier
# a) 5 premieres lignes
head -n 5 /etc/passwd
# Variante courte
head -5 /etc/passwd

# b) 20 dernieres lignes
tail -n 20 /var/log/syslog
tail -20 /var/log/syslog

# c) Suivre en temps reel
tail -f /var/log/syslog
# Bonus : tail -F suit meme apres rotation (logrotate)

Astuces :

Question 15 / 16 tout assembler

Le script de sauvegarde complet

Composez le script sauvegarde-ircd.sh qui combine tout : mkdir -p, tar -C, date, et rotation 14 jours.

Ecrivez le script complet :

#!/bin/bash
# sauvegarde-ircd.sh
set -e

REP_SOURCE="/var/lib/ircd-hybrid"
REP_BACKUP="/var/backups/ircd"
aujourdhui=$(date +%Y-%m-%d)
NOM_ARCHIVE="ircd-${aujourdhui}.tgz"
JOURS_RETENTION=14

# Creer le repertoire de backup (idempotent)
mkdir -p "$REP_BACKUP"

# Archiver avec chemin relatif (le -C)
tar -czf "${REP_BACKUP}/${NOM_ARCHIVE}" \
    -C "$(dirname "$REP_SOURCE")" \
    "$(basename "$REP_SOURCE")"

# Rotation : supprimer les archives de plus de N jours
find "$REP_BACKUP" -name "ircd-*.tgz" -type f \
    -mtime +${JOURS_RETENTION} -delete

echo "Sauvegarde : ${REP_BACKUP}/${NOM_ARCHIVE}"

Reflexes appliques :

Question 16 / 16 verifier l'archive

Verifier qu'une archive est saine

Vous voulez ajouter une etape de verification a la fin du script : confirmer que l'archive cree est lisible et qu'elle contient bien des fichiers.

Donnez 2 commandes : une qui teste l'integrite gzip, une qui compte le nombre de fichiers dans l'archive :

# Tester l'integrite gzip (sortie 0 si OK)
gunzip -t /var/backups/ircd/ircd-2026-05-22.tgz
# Ou plus court
gzip -t /var/backups/ircd/ircd-2026-05-22.tgz

# Compter les fichiers dans l'archive
tar -tzf /var/backups/ircd/ircd-2026-05-22.tgz | wc -l

Bonus : integration dans le script

# Bloc de verification a la fin du script
if ! gzip -t "${REP_BACKUP}/${NOM_ARCHIVE}"; then
    echo "ERREUR : archive corrompue" >&2
    exit 1
fi

NB_FICHIERS=$(tar -tzf "${REP_BACKUP}/${NOM_ARCHIVE}" | wc -l)
if [ "$NB_FICHIERS" -lt 1 ]; then
    echo "ERREUR : archive vide" >&2
    exit 1
fi
echo "Archive OK : ${NB_FICHIERS} fichiers"

Cela transforme la sauvegarde en sauvegarde verifiee. Indispensable si on veut etre sure qu'on a vraiment quelque chose en cas de pepin.

Bilan

Ce que vous venez de pratiquer

Supplement (non evalue) : bits speciaux sticky / suid / guid

R pour recommencer.

« Retour aux mini-tests