Mini-test 2
Dates, archives, tests d'existence, recherche par nom et par contenu, sauvegarde rotative
16 questions + 1 supplement
Cliquez Voir la solution sur chaque slide
Question 1 / 16 tar : c / t / x
archives.tgz.
archives.tgz a partir de /etc/ircd-hybrid/ :archives.tgz sans 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.
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 :
c create (creer) / t tlist (lister) / x extract (extraire)z = compression gzip (sortie ou entree .tgz)f FICHIER = nom du fichier d'archive (toujours le DERNIER switch avant le nom)v bonus : verbose (afficher la liste des fichiers traites)Autres formats : -j pour bzip2 (.tbz2), -J pour xz (.txz), --zstd pour zstd.
Question 2 / 16 la commande date
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 :
2026-05-22aujourdhuiNAME
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 ?
ls -1 donne les sauvegardes dans l'ordre)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
/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) :
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 :
$(date +%Y-%m-%d) = substitution de commande, format trie naturellement-c = create, -z = gzip, -f = nom du fichier%Y-%m-%d (avec tirets) : le tri alphabetique correspond au tri chronologique%d-%m-%Y qui trie mal (les 01-* viennent avant les annees)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
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 :
/var/lib/ircd-hybrid/ircd-hybrid/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
/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 :
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 :
/var, /var/backups, puis /var/backups/ircd)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
backup-AAAA-MM-JJ.tgz
(ex. backup-2026-05-13.tgz) du repertoire /var/lib/ircd-hybrid/.
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).
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.
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 ]
/etc/ircd-hybrid/ircd.conf n'existe pas, le copier depuis le modele /etc/ircd-hybrid/ircd.conf.default :/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 ... ].
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 :
-f fichier ordinaire existe-d repertoire existe-e existe (fichier OU repertoire OU lien)-r lisible / -w ecrivable / -x executable-s existe ET non videVariante 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
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 :
%Y-%m-%d) dans une variable aujourdhui/var/backups/ircd s'il n'existe pas (idempotent)/var/lib/ircd-hybrid existe ; sinon affiche un message et sort avec code 1/var/backups/ircd/ircd-AAAA-MM-JJ.tgz avec chemin relatif (utilise -C)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 :
set -e : arret au premier echec (filet de securite)aujourdhui=$(date +%Y-%m-%d) : substitution de commande pour capturer la datemkdir -p : ne plante pas si le repertoire existe deja[ ! -d ... ] : test inverse, sortie si la source manquetar -czf ... -C dir nom : archive avec chemin relatif dans l'archive>&2 sur les erreurs : envoyer le message vers stderr (pas stdout)Ce qu'on n'a PAS encore fait (et qui vient apres) :
find -mtime)grep -r)gzip -t)Question 9 / 16 find : par nom
.conf quelque part sous /etc/ :.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).
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 :
-type f seulement les fichiers, -type d seulement les repertoires-mtime -N = moins de N jours / +N = plus de N jours-size +10M = plus de 10 megas-user nadine = appartenant a un utilisateur precis-iname = insensible a la casseActions a la fin : -print (defaut), -delete, -exec cmd {} +.
Question 10 / 16 rotation : effacer les vieilles
.tgz dans /var/backups/ircd/ et effacer le reste.Donnez la commande find qui supprime les fichiers .tgz de plus de 14 jours :
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 :
-name "*.tgz" = seulement les fichiers d'archive-type f = seulement les fichiers (pas les repertoires)-mtime +14 = modifies il y a plus de 14 jours-delete = supprimer les correspondancesPiege 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
Trouver des fichiers par nom, par age, par contenu
5 questions
Combiner les outils trouver, filtrer, compter
Question 11 / 16 grep : par contenu
port 6667 dans tous les fichiers de /etc/ircd-hybrid/ :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.
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 :
-r ou -R recursif-l liste les noms de fichiers (l = "files with match")-L liste les fichiers SANS match (l'inverse)-i insensible a la casse-n numero de ligne-c compte les matches par fichier-v inverser (afficher les lignes qui NE matchent PAS)-E regex etendue (alternation foo|bar)Question 12 / 16 find + grep
Listez tous les fichiers .conf sous /etc/ qui contiennent enable_ssl=yes. Une seule commande, en chainant find et grep :
-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".
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 ?
find -exec ... {} + : ramasse plusieurs fichiers
dans un seul appel a grep. Sur, marche partout.grep -r --include : plus court a taper, mais
limite aux jokers simples sur le nom.find | xargs grep : pratique pour chainer.
Probleme avec les noms qui contiennent des espaces (utiliser
find ... -print0 | xargs -0 grep).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)
wc (word count) compte non seulement les mots, mais aussi
lignes, caracteres, octets... selon les options.
/var/log/auth.log :/etc/motd :/etc/passwd :/etc/services :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
Non evalue a l'examen mais utile a connaitre
Bits speciaux
Supplement bits speciaux (non evalue)
/tmp (octal et symbolique) :/usr/local/bin/mon-outil (utile pour qu'il tourne en tant que owner) :+t sticky, u+s suid,
g+s guid.
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 :
drwxrwxrwt : sticky bit (le t a la place du x des autres)-rwsr-xr-x : suid (le s dans la position user)-rwxr-sr-x : guid (le s dans la position group)Utilisations classiques :
/tmp, repertoires partages multi-utilisateurs/usr/bin/passwd (modifie /etc/shadow en root)Attention : suid est un risque de securite si mal utilise. Toujours auditer avec find / -perm -4000 -type f.
Question 14 / 16 previsualiser (head, tail)
head et tail sont les outils pour regarder
rapidement les premieres ou les dernieres lignes d'un fichier - tres
utile pour les gros logs.
/etc/passwd :/var/log/syslog :/var/log/syslog :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
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 :
head -n -10 : tout SAUF les 10 dernieres lignestail -n +10 : a partir de la ligne 10 (inclus)head -n 110 fichier | tail -n 10 : les lignes 101-110tail -F (majuscule) : essentiel pour logrotate / fichiers tournantsQuestion 15 / 16 tout assembler
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 :
set -e en haut : arret au premier echecQuestion 16 / 16 verifier l'archive
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
-l = noms seulement)Supplement (non evalue) : bits speciaux sticky / suid / guid
R pour recommencer.