← retour aux snippets

mktemp et écritures atomiques

Créer des fichiers temporaires sûrs et écrire de façon atomique avec nettoyage automatique.

objectif

Créer des fichiers temporaires uniques, éviter les collisions et écrire de manière atomique pour ne jamais laisser de fichiers partiels.

code minimal

# crée un fichier temporaire et le supprime à la fin
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

# écrire dans le tmp puis remplacer la cible de façon atomique
commande_qui_genere > "$tmp"
mv -f "$tmp" fichier_cible

utilisation

# téléchargement sûr: jamais de JSON corrompu en cas d'échec
tmp="$(mktemp)"; trap 'rm -f "$tmp"' EXIT
curl -fsSL --connect-timeout 5 --max-time 15 \
  --retry 3 --retry-delay 2 --retry-all-errors \
  "https://api.data.pm/data.json" > "$tmp"
mv -f "$tmp" data.json

# mise à jour JSON sûre avec jq
tmp="$(mktemp)"; trap 'rm -f "$tmp"' EXIT
jq '.enabled=true' config.json > "$tmp"
mv -f "$tmp" config.json

# générer puis déplacer dans le même dossier (meilleure atomicité)
tmp="$(mktemp -p . .config.json.XXXXXX)"; trap 'rm -f "$tmp"' EXIT
commande_qui_modifie > "$tmp"
mv -f "$tmp" ./config.json

variante(s) utile(s)

# dossier temporaire pour plusieurs fichiers
tmpdir="$(mktemp -d)"; cleanup() { rm -rf "$tmpdir"; }; trap cleanup EXIT
commande_a > "$tmpdir/a"; commande_b > "$tmpdir/b"
tar -cf archive.tar -C "$tmpdir" .

# gérer les signaux et erreurs proprement
set -Eeuo pipefail
tmp="$(mktemp)"; cleanup() { rm -f "$tmp"; }; trap cleanup EXIT INT TERM HUP
commande_risqueuse > "$tmp"
mv -f "$tmp" resultat.txt

# restreindre les permissions lors de la création (évite les fuites)
umask 077
tmp="$(mktemp)"

notes

  • mv est atomique uniquement si source et destination sont sur le même système de fichiers; utilisez -p . pour créer le tmp dans le dossier cible.
  • trap ... EXIT garantit le nettoyage même en cas d’erreur; ajoutez INT TERM HUP pour gérer les signaux.
  • fixez umask 077 pour des fichiers temporaires non lisibles par d’autres utilisateurs.
  • évitez sed -i non portable: préférez mktemp + mv pour un comportement fiable entre GNU/BSD.