Linux / Commande mktemp : créer et nettoyer des fichiers temporaires
mktemp crée immédiatement un fichier ou un répertoire temporaire avec un nom difficile à prédire, puis affiche son chemin. Utilisez mktemp pour un fichier et mktemp -d pour un dossier ; vérifiez la réussite avant d’utiliser le chemin et prévoyez vous-même le nettoyage, car le programme ne supprime pas automatiquement ce qu’il crée.
Cette création est préférable à un nom fabriqué avec le seul identifiant du processus : elle évite la séparation entre « choisir un nom supposé libre » et « créer l’objet ». La protection de l’ensemble du travail dépend aussi du répertoire parent, des permissions et de l’absence de remplacement ultérieur du chemin.
Créer un fichier et utiliser le chemin retourné
temporaire=$(mktemp) || exit 1
printf 'Chemin : %s\n' "$temporaire"
test -f "$temporaire" || exit 1
printf '%s\n' 'contenu temporaire' > "$temporaire"
cat -- "$temporaire"
rm -- "$temporaire"
Le chemin varie d’un appel à l’autre. Le fichier existe avant la première écriture, et cat affiche contenu temporaire. La dernière ligne supprime uniquement ce fichier lorsque vous avez fini de l’examiner ; elle ne concerne aucun autre fichier du répertoire temporaire.
L’affectation avec $(...) capture la sortie standard, tandis que || exit 1 arrête ce fragment en cas d’échec de création. Sans ce contrôle, une variable vide ou inutilisable peut conduire la suite du script à agir au mauvais endroit. Gardez toujours les guillemets autour du chemin pour préserver les espaces et les caractères particuliers.
Sur GNU, un fichier créé reçoit normalement les permissions de lecture et d’écriture pour le propriétaire, sans accès pour le groupe ni les autres, soit 0600 avant les restrictions supplémentaires d’umask. Cela n’est pas un chiffrement et ne protège pas contre tout compte privilégié ou processus ayant les mêmes droits.
Choisir un nom avec un modèle et un suffixe
temporaire=$(mktemp -- rapport.XXXXXX) || exit 1
printf '%s\n' "$temporaire"
rm -- "$temporaire"
journal=$(mktemp --suffix=.log -- application.XXXXXX) || exit 1
printf '%s\n' "$journal"
rm -- "$journal"
Dans GNU, un modèle explicite doit comporter au moins trois X consécutifs dans son dernier composant. La dernière série de X est remplacée ; un suffixe comme .log peut être ajouté avec --suffix. Si vous choisissez --suffix explicitement, le modèle doit se terminer par X et le suffixe ne doit pas contenir de barre oblique.
Vous pouvez aussi fournir un modèle comme rapport.XXXXXX.csv, dont GNU déduit le suffixe. Ne remplacez pas les X à la main et ne réutilisez pas un chemin observé lors d’une exécution précédente comme s’il était encore réservé pour vous.
Un modèle relatif explicite sans -p ni --tmpdir est créé à partir du répertoire courant, même si TMPDIR est défini. À l’inverse, l’appel sans modèle utilise le modèle GNU par défaut tmp.XXXXXXXXXX avec --tmpdir implicite. Ce détail explique pourquoi deux formes qui se ressemblent peuvent créer leurs fichiers dans des dossiers différents.
Sélectionner le répertoire parent et TMPDIR
| Forme GNU | Emplacement | À retenir |
|---|---|---|
mktemp |
TMPDIR s’il est disponible, sinon /tmp | Modèle et --tmpdir implicites |
mktemp modele.XXXXXX |
Répertoire courant pour ce modèle relatif | Ne reprend pas automatiquement TMPDIR |
mktemp -p DOSSIER modele.XXXXXX |
Dossier explicite | Le dossier doit déjà exister |
mktemp --tmpdir modele.XXXXXX |
TMPDIR ou /tmp | La forme longue sans valeur choisit l’environnement |
Choisissez un parent que vous contrôlez et dont les droits conviennent à vos données. mktemp ne crée pas automatiquement les répertoires intermédiaires manquants d’un modèle. Avec -p ou --tmpdir, le modèle est relatif au parent et ne doit pas être absolu.
base=$(mktemp -d) || exit 1
fichier=$(mktemp --tmpdir="$base" -- resultat.XXXXXX) || exit 1
printf 'Base : %s\nFichier : %s\n' "$base" "$fichier"
test -f "$fichier" || exit 1
rm -- "$fichier"
rmdir -- "$base"
Ce test crée un parent privé et un fichier à l’intérieur, puis les retire dans cet ordre. Le choix -p est utile lorsque les fichiers de travail doivent rester sur un volume précis pour des raisons d’espace ou pour une opération de déplacement prévue sur ce même système de fichiers.
base=$(mktemp -d) || exit 1
temporaire=$(TMPDIR="$base" mktemp) || exit 1
printf '%s\n' "$temporaire"
rm -- "$temporaire"
rmdir -- "$base"
L’affectation TMPDIR ne concerne ici que le processus mktemp appelé. Elle ne déplace pas des fichiers déjà créés et ne change pas définitivement l’environnement du shell parent. Le guide des variables d’environnement et de env explique cette portée.
L’ancienne option -t est dépréciée dans GNU. Préférez -p ou --tmpdir et vérifiez mktemp --help si le script doit aussi fonctionner avec une autre implémentation Unix.
Créer un espace de travail et le nettoyer à la sortie
Un répertoire créé par -d donne un espace dans lequel vous pouvez employer des noms internes fixes, sans demander un nom aléatoire pour chaque fichier. Sur GNU, ses droits normaux sont lecture, écriture et traversée pour le propriétaire uniquement, soit 0700 avant les restrictions supplémentaires d’umask.
Le script complet suivant utilise Bash. Enregistrez-le sous rapport-temporaire.sh puis exécutez bash rapport-temporaire.sh. Il crée un seul rapport, l’affiche et nettoie cet espace à la sortie normale ou lors des signaux qu’il intercepte.
#!/usr/bin/env bash
umask 077
travail=$(mktemp -d) || {
printf '%s\n' 'Impossible de créer l’espace temporaire.' >&2
exit 1
}
nettoyer() {
statut=$?
trap - EXIT
echec_nettoyage=0
rm -f -- "$travail/rapport.txt" || echec_nettoyage=1
rmdir -- "$travail" || echec_nettoyage=1
if [ "$echec_nettoyage" -ne 0 ]; then
printf 'Nettoyage incomplet : %q\n' "$travail" >&2
if [ "$statut" -eq 0 ]; then
statut=1
fi
fi
exit "$statut"
}
trap nettoyer EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
printf '%s\n' 'rapport temporaire' > "$travail/rapport.txt" || exit "$?"
cat -- "$travail/rapport.txt"
Vous devez voir rapport temporaire, et le statut final doit être 0 si la lecture et le nettoyage ont réussi. La fonction de sortie récupère d’abord le statut du travail principal. Elle conserve un échec principal et signale aussi un nettoyage incomplet ; si le travail avait réussi mais que le nettoyage échoue, le script renvoie 1.
Le nettoyage vise seulement rapport.txt, puis utilise rmdir, qui refuse un dossier non vide. Si vous ajoutez un autre fichier au script sans adapter sa politique de nettoyage, l’espace est conservé avec un diagnostic plutôt que supprimé récursivement. Les guillemets et -- protègent les chemins ; le trap n’est installé qu’après une création réussie.
Les traps HUP, INT et TERM demandent une sortie avec les statuts choisis par ce script, puis le trap EXIT de Bash exécute le nettoyage. Un arrêt brutal, une panne de courant ou un signal impossible à intercepter comme SIGKILL ne permettent pas de garantir ce nettoyage. Une politique système de purge des temporaires peut compléter le script, mais ne remplace pas son contrôle des chemins.
Éviter -u et distinguer création, erreur et nettoyage
mktemp -u, ou --dry-run, affiche un nom sans créer l’objet. Un autre processus peut prendre ce nom avant votre écriture : cette séparation réintroduit la course que mktemp doit justement éviter. N’utilisez donc pas la sortie de -u pour réserver un fichier destiné à être ouvert plus tard.
-q masque les diagnostics de création, mais pas le statut d’échec. Le modèle, le parent, l’espace disponible, les limites de fichiers et les permissions restent à vérifier ; un résultat silencieux ne prouve pas qu’un objet a été créé.
espace_q=$(mktemp -d) || exit 1
if temporaire=$(mktemp -q --tmpdir="$espace_q/parent-absent" -- rapport.XXXXXX); then
printf 'Créé : %s\n' "$temporaire"
rm -- "$temporaire"
else
printf '%s\n' 'Création impossible : le parent demandé manque.' >&2
fi
rmdir -- "$espace_q"
Cet exemple prend la branche d’échec car le parent demandé n’existe pas dans le nouvel espace. Le test porte sur le statut de mktemp, sans se fier au diagnostic de création supprimé par -q. Une erreur de modèle, par exemple seulement deux X, peut encore produire un diagnostic même avec -q : cette option ne garantit pas un silence absolu pour toutes les erreurs.
Un nom imprévisible ne suffit pas à protéger tout le cycle de vie du fichier. Ne placez pas aveuglément des données sensibles dans un parent modifiable par une autre personne, ne changez pas les permissions pour rendre l’espace public sans raison et gardez les fichiers de travail à l’intérieur du dossier créé.
Choisir mktemp selon le besoin réel
mktemp convient lorsque vous avez besoin d’un nouvel objet de travail avec un nom distinct. touch convient à un nom fixe choisi à l’avance, mais ne réserve pas à lui seul un espace de travail privé contre un remplacement hostile. mkdir permet de créer un dossier permanent identifié ; mktemp -d combine le choix d’un nom temporaire et sa création.
Le manuel GNU de mktemp décrit les modèles, droits et priorités d’emplacement. Vérifiez séparément le type de stockage utilisé : un répertoire temporaire peut être sur disque ou en mémoire, et sa présence dans les sauvegardes, snapshots ou le swap dépend de la configuration.
Supprimer un temporaire ne démontre pas un effacement confidentiel de toutes ses anciennes données. Choisissez l’emplacement et la conservation selon la nature des informations, puis nettoyez exactement les objets que votre programme a créés. Si vous devez journaliser un nom contenant des caractères spéciaux dans Bash, le format printf %q est plus lisible qu’une ligne ambiguë ; pour sa résolution, le guide de realpath distingue le chemin calculé d’un véritable contrôle d’accès.




