Fichiers temporaires sûrs et répertoires de verrouillage
Utilisez mktemp et flock pour créer des ressources temporaires sans conditions de concurrence et empêcher l’exécution simultanée de scripts.
Fichiers temporaires sûrs et répertoires de verrouillage est une leçon Linux Command Line & Bash Scripting Mastery gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Linux Command Line & Bash Scripting Mastery, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Linux Command Line & Bash Scripting Mastery comprend 4 leçons au total.
Pourquoi les fichiers temporaires présentent un risque de sécurité
Les scripts Bash ont fréquemment besoin d’un stockage temporaire — résultats intermédiaires, marqueurs de verrouillage ou zones de préparation. Mais créer des fichiers temporaires sans précaution ouvre la voie à de graves vulnérabilités.
- Conditions de concurrence : un autre processus peut deviner votre nom de fichier et créer le fichier avant vous, redirigeant ainsi vos écritures.
- Attaques par liens symboliques : un attaquant crée un lien symbolique au chemin attendu, qui pointe vers un fichier sensible comme
/etc/passwd. - Fichiers résiduels : si un script plante, les fichiers temporaires s’accumulent et peuvent exposer des données sensibles.
Les deux outils essentiels qui éliminent ces problèmes sont mktemp et flock. Cette leçon vous montre comment les utiliser de manière sûre et défensive.
Créer des fichiers temporaires sûrs avec mktemp
mktemp crée un fichier temporaire avec un nom aléatoire et imprévisible, puis renvoie son chemin. Il crée le fichier de manière atomique, de sorte qu’aucun autre processus ne puisse s’emparer du nom avant vous.
- Syntaxe :
mktemp [TEMPLATE]— le modèle doit se terminer par au moins trois caractèresX. - Chaque
Xest remplacé par un caractère aléatoire, ce qui produit un nom unique comme/tmp/script.aB3kQz. - Le fichier est automatiquement créé avec les permissions
0600(lisible uniquement par son propriétaire).
Capturez toujours immédiatement le chemin renvoyé dans une variable afin de pouvoir le référencer et le supprimer plus tard.
#!/usr/bin/env bash
set -euo pipefail
# Create a secure temp file
TMPFILE=$(mktemp /tmp/myapp.XXXXXX)
echo "Temp file created at: $TMPFILE"
# Write data to it
echo "some intermediate result" > "$TMPFILE"
# Read it back
cat "$TMPFILE"
# Clean up
rm -f "$TMPFILE"Toujours effectuer le nettoyage avec trap
Si votre script se termine de manière inattendue — à cause d’une erreur, d’un signal ou du déclenchement de set -e — les fichiers temporaires resteront présents, sauf si vous enregistrez un gestionnaire de nettoyage.
La commande intégrée trap exécute une commande lorsque le shell reçoit un signal ou se termine. Le modèle classique pour nettoyer les fichiers temporaires est le suivant :
- Enregistrez le gestionnaire immédiatement après avoir créé le fichier temporaire.
- Utilisez
EXITafin que le nettoyage s’exécute lors d’une fin normale comme anormale. - Gérez également
INTetTERMsi le script s’exécute longtemps ou est interactif.
Cela garantit l’absence de fichiers orphelins, même si le script est interrompu en cours d’exécution.
#!/usr/bin/env bash
set -euo pipefail
TMPFILE=$(mktemp /tmp/report.XXXXXX)
# Register cleanup before doing any real work
cleanup() {
rm -f "$TMPFILE"
echo "Cleaned up $TMPFILE" >&2
}
trap cleanup EXIT
# Do work — even if this fails, cleanup() will run
echo "Processing..." > "$TMPFILE"
grep "result" "$TMPFILE" || true
echo "Done. File will be removed on exit."Créer des répertoires temporaires avec mktemp -d
Vous avez parfois besoin d'un répertoire entier pour préparer plusieurs fichiers — par exemple pour créer une archive ou extraire une archive tar avant son traitement. Utilisez mktemp -d pour créer un répertoire temporaire sécurisé.
- Le répertoire est créé avec les permissions
0700(accès réservé au propriétaire). - Effectuez le nettoyage avec
rm -rfdans votre interception — veillez à supprimer uniquement la variable, jamais un chemin écrit en dur. - Utilisez les guillemets doubles et vérifiez que la variable n'est pas vide avant d'appeler
rm -rf, comme mesure de sécurité supplémentaire.
#!/usr/bin/env bash
set -euo pipefail
TMPDIR=$(mktemp -d /tmp/extract.XXXXXX)
cleanup() {
# Guard: only rm if variable is set and non-empty
[[ -n "${TMPDIR:-}" ]] && rm -rf "$TMPDIR"
}
trap cleanup EXIT
echo "Working in $TMPDIR"
# Simulate staging files
echo "file one" > "$TMPDIR/part1.txt"
echo "file two" > "$TMPDIR/part2.txt"
ls "$TMPDIR"
echo "All done."Le problème des exécutions simultanées de scripts
Les tâches cron, les minuteurs systemd et les scripts déclenchés manuellement peuvent facilement lancer plusieurs instances du même script simultanément. Cela entraîne :
- Traitement en double : les mêmes enregistrements de base de données ou fichiers sont traités deux fois.
- Sortie corrompue : deux instances écrivent simultanément dans le même fichier de sortie.
- Interblocages ou état partiel : les deux instances modifient des ressources partagées dans un ordre entrelacé et imprévisible.
La solution traditionnelle consistait à écrire un fichier PID et à le vérifier au démarrage — mais cette approche présente une fenêtre de concurrence entre la vérification et l'écriture. La solution moderne correcte est flock, qui utilise le mécanisme de verrouillage consultatif du noyau pour garantir un verrou exempt de condition de concurrence.
Verrouillage avec flock : le modèle en une seule ligne
flock acquiert un verrou consultatif sur un descripteur de fichier avant d'exécuter une commande. L'utilisation la plus simple consiste à encapsuler l'intégralité de votre script depuis la ligne de commande :
flock -n /var/lock/myscript.lock bash myscript.sh
-n(sans blocage) : quitte immédiatement avec le statut 1 si le verrou est déjà détenu, au lieu d'attendre.- Sans
-n,flockbloque jusqu'à ce que le verrou soit disponible — ce qui est utile pour mettre les exécutions en file d'attente. - Le fichier de verrouillage lui-même n'est qu'un marqueur ; son contenu n'a aucune importance. Vous pouvez le conserver entre les exécutions sans danger.
- Lorsque le processus détenant le verrou se termine, le noyau le libère automatiquement — aucun nettoyage manuel n'est nécessaire.
#!/usr/bin/env bash
# launcher.sh — prevents concurrent runs of worker.sh
set -euo pipefail
LOCKFILE="/tmp/myworker.lock"
if ! flock -n "$LOCKFILE" bash -c 'echo "Running worker..."; sleep 2; echo "Done."'; then
echo "Another instance is already running. Exiting." >&2
exit 1
fiUtiliser flock dans un script avec un descripteur de fichier
Pour effectuer le verrouillage dans un script plutôt que de l'encapsuler depuis l'extérieur, utilisez exec pour ouvrir un descripteur de fichier, puis appelez flock sur ce descripteur. Il s'agit du modèle idiomatique utilisé dans les scripts de production.
exec 200>"$LOCKFILE"ouvre le fichier sur le descripteur 200 en écriture (en le créant si nécessaire).flock -n 200tente de verrouiller le descripteur 200 sans blocage.- Comme le verrou est associé au descripteur de fichier (et non au nom du fichier), il est libéré automatiquement à la fin du processus du shell.
- Les numéros de descripteur 200 à 299 sont traditionnellement utilisés pour éviter les conflits avec l'entrée standard, la sortie standard et la sortie d'erreur standard.
#!/usr/bin/env bash
set -euo pipefail
LOCKFILE="/tmp/myjob.lock"
# Open lock file on FD 200
exec 200>"$LOCKFILE"
# Attempt non-blocking lock
if ! flock -n 200; then
echo "ERROR: Another instance of this script is running." >&2
exit 1
fi
echo "Lock acquired. Starting work..."
sleep 1
echo "Work complete. Lock will be released on exit."Combiner mktemp et flock dans un seul script
Les scripts réellement défensifs ont besoin des deux : d'un verrou pour empêcher les exécutions simultanées et de fichiers temporaires sécurisés pour les données intermédiaires. Voici le modèle complet combinant ces deux techniques :
- Acquérez d'abord le verrou — avant de créer des fichiers temporaires — afin qu'une seule instance effectue quoi que ce soit.
- Créez les ressources temporaires après avoir confirmé l'acquisition du verrou.
- Enregistrez l'
trapimmédiatement après avoir créé les ressources temporaires afin de garantir le nettoyage, quelle que soit la manière dont le script se termine. - Le fichier de verrouillage ne doit jamais se trouver dans le répertoire temporaire — il doit persister entre les exécutions pour que
flockpuisse y faire référence.
#!/usr/bin/env bash
set -euo pipefail
LOCKFILE="/tmp/report_builder.lock"
exec 200>"$LOCKFILE"
if ! flock -n 200; then
echo "Already running — aborting." >&2
exit 1
fi
# Now safe to create temp resources
TMPDIR=$(mktemp -d /tmp/report.XXXXXX)
TMPLOG=$(mktemp /tmp/report_log.XXXXXX)
cleanup() {
rm -rf "${TMPDIR:-}"
rm -f "${TMPLOG:-}"
}
trap cleanup EXIT
echo "Building report in $TMPDIR" | tee "$TMPLOG"
echo "Step 1 complete" >> "$TMPLOG"
cat "$TMPLOG"Les répertoires de verrouillage comme mécanisme alternatif
Sur les systèmes où flock n'est pas disponible (certains systèmes embarqués ou systèmes de fichiers réseau comme NFS), vous pouvez utiliser des répertoires de verrouillage. mkdir est atomique sur les systèmes POSIX : il ne réussit que si le répertoire n'existe pas déjà.
- Créez le répertoire de verrouillage avec
mkdir /tmp/myscript.lock.d— si une autre instance l'a déjà créé,mkdiréchoue immédiatement. - Stockez les métadonnées (comme le PID) dans le répertoire à des fins de diagnostic.
- Supprimez toujours le répertoire dans une
trapsurEXIT. - Attention : contrairement à
flock, un verrou de répertoire n'est NOT pas libéré automatiquement si le processus est tué avec-9ou si la machine redémarre — ajoutez une vérification de détection des verrous obsolètes.
#!/usr/bin/env bash
set -euo pipefail
LOCKDIR="/tmp/myscript.lock.d"
# Atomic mkdir — fails if directory already exists
if ! mkdir "$LOCKDIR" 2>/dev/null; then
# Check if the holding PID is still alive
HOLDER_PID=$(cat "$LOCKDIR/pid" 2>/dev/null || echo "")
if [[ -n "$HOLDER_PID" ]] && kill -0 "$HOLDER_PID" 2>/dev/null; then
echo "Locked by PID $HOLDER_PID. Exiting." >&2
exit 1
else
echo "Stale lock detected. Removing and continuing." >&2
rm -rf "$LOCKDIR"
mkdir "$LOCKDIR"
fi
fi
echo "$$" > "$LOCKDIR/pid"
trap 'rm -rf "$LOCKDIR"' EXIT
echo "Lock acquired via directory. Running..."
sleep 1
echo "Done."Attendre avec un délai d'expiration avec flock
Vous pouvez parfois vouloir attendre un verrou plutôt qu'échouer immédiatement — mais sans attendre indéfiniment. flock prend en charge un délai d'expiration avec l'option -w.
flock -w 10 200attend jusqu'à 10 secondes le verrou, puis quitte avec le statut 1 s'il est toujours indisponible.- C'est idéal pour les scripts qui doivent se mettre en file derrière un processus précédent de courte durée, mais abandonner si celui-ci est bloqué.
- Associez
-wà un message d'erreur explicite qui fournit le contexte — le chemin du fichier de verrouillage et la durée de l'attente — afin que les opérateurs puissent diagnostiquer rapidement les blocages.
#!/usr/bin/env bash
set -euo pipefail
LOCKFILE="/tmp/data_sync.lock"
TIMEOUT=15
exec 200>"$LOCKFILE"
echo "Waiting up to ${TIMEOUT}s for lock on $LOCKFILE..."
if ! flock -w "$TIMEOUT" 200; then
echo "ERROR: Could not acquire lock after ${TIMEOUT}s." \
"Another instance may be hung." >&2
exit 1
fi
echo "Lock acquired. Syncing data..."
sleep 1
echo "Sync complete."Liste de contrôle défensive : ressources temporaires sécurisées
Avant de distribuer un script qui utilise des fichiers temporaires ou un verrouillage, parcourez cette liste de contrôle :
- Utilisez
mktemp, jamais des chemins écrits en dur —/tmp/myapp.tmpest prévisible et exploitable. - Capturez immédiatement le chemin —
TMPFILE=$(mktemp ...)avant toute autre commande. - Enregistrez
trap cleanup EXITimmédiatement après la création — et non à la fin du script. - Entourez toutes les utilisations de variables de guillemets doubles —
rm -f "$TMPFILE", jamaisrm -f $TMPFILE. - Préférez
flockaux fichiers PID — gestion par le noyau et libération automatique en cas d'incident. - Utilisez
-nsans blocage par défaut — les verrous silencieusement bloquants masquent les problèmes de performance. - Placez le fichier de verrouillage en dehors du répertoire temporaire — afin qu'il survive à l'interception de nettoyage.
- Testez le comportement du nettoyage — exécutez votre script et appliquez-lui
kill -9en cours d'exécution ; vérifiez qu'il ne reste aucun fichier (pour les scripts fondés surflock; les verrous de répertoire nécessitent davantage de précautions).
Vérification des connaissances : comportement des options de flock
Une tâche cron s'exécute chaque minute et traite un fichier partagé. Vous voulez que toute nouvelle invocation quitte immédiatement avec une erreur si une exécution précédente est toujours active, sans attendre. Quelle invocation de flock répond correctement à ce besoin ?
Récapitulatif : fichiers temporaires sécurisés et répertoires de verrouillage
Dans cette leçon, vous avez découvert les deux outils essentiels de gestion défensive des ressources dans Bash :
mktempcrée des fichiers temporaires (0600) et des répertoires (0700) aux permissions sécurisées et aux noms imprévisibles, éliminant les conditions de concurrence et les attaques par lien symbolique qui affectent les chemins écrits en dur.trap cleanup EXITgarantit la suppression des fichiers temporaires à chaque sortie — normale, provoquée par une erreur ou par un signal — lorsqu'il est enregistré immédiatement après la création.flockfournit un verrouillage consultatif imposé par le noyau : utilisez-npour échouer rapidement en cas de conflit,-w Npour attendre avec un délai d'expiration, et le modèleexec 200>filepour verrouiller dans le script, le noyau libérant automatiquement le verrou à la fin du processus.- Les répertoires de verrouillage (
mkdir) offrent une solution de repli portable dans les environnements oùflockn'est pas disponible, mais nécessitent une détection explicite des verrous obsolètes. - Conservez toujours le fichier de verrouillage en dehors du répertoire temporaire et utilisez les guillemets doubles pour chaque variable utilisée lors du nettoyage.
La combinaison de mktemp + flock + trap vous permet d'écrire des scripts protégés contre les invocations simultanées, les plantages imprévisibles et les manipulations malveillantes du système de fichiers.
Questions Fréquemment Posées
La leçon « Fichiers temporaires sûrs et répertoires de verrouillage » est-elle gratuite ?
Oui — le texte complet de « Fichiers temporaires sûrs et répertoires de verrouillage » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Linux Command Line & Bash Scripting Mastery, passe à CoddyKit PRO. Le cours Linux Command Line & Bash Scripting Mastery comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Fichiers temporaires sûrs et répertoires de verrouillage » ?
Utilisez mktemp et flock pour créer des ressources temporaires sans conditions de concurrence et empêcher l’exécution simultanée de scripts. Tu pratiques Linux Command Line & Bash Scripting Mastery avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Linux Command Line & Bash Scripting Mastery ?
Aucune expérience préalable n'est requise. Linux Command Line & Bash Scripting Mastery sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Fichiers temporaires sûrs et répertoires de verrouillage » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Linux Command Line & Bash Scripting Mastery ?
Oui. Chaque leçon Linux Command Line & Bash Scripting Mastery inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Mode strict avec set -euo pipefail
- Gestionnaires trap pour le nettoyage et les signaux
- Fichiers temporaires sûrs et répertoires de verrouillage
- Scripts idempotents et logique de nouvelle tentative avec temporisation