175 votes

Création de fichiers temporaires en bash

Existe-t-il objectivement de meilleures façons de créer des fichiers temporaires dans les scripts bash ?

Normalement, je leur donne le nom qui me vient à l'esprit, comme tempfile-123, puisqu'il sera supprimé lorsque le script sera terminé. Y a-t-il un inconvénient à faire cela autre que l'écrasement d'un éventuel tempfile-123 dans le dossier actuel ? Ou y a-t-il un avantage à créer un fichier temporaire d'une manière plus prudente ?

1 votes

N'utilisez pas de fichiers temporaires. Utilisez plutôt des répertoires temporaires. Et n'utilisez pas mktemp. Voir ici pourquoi : codeproject.com/Articles/15956/

25 votes

Cet article est tout simplement faux, du moins lorsqu'il est appliqué à la commande shell mktemp (par opposition à l'appel de la bibliothèque mktemp). Comme mktemp crée le fichier lui-même avec un umask restrictif, l'attaque donnée ne fonctionne que si l'attaquant opère sous le même compte que l'attaqué... auquel cas la partie est déjà perdue. Pour les meilleures pratiques dans le monde des scripts shell, voir mywiki.wooledge.org/BashFAQ/062

0 votes

Vous pouvez également utiliser tempfile(1) sur les systèmes qui en disposent.

202voto

kojiro Points 24374

Le site mktemp(1) l'explique assez bien :

Traditionnellement, de nombreux scripts shell prennent le nom du programme avec le pid comme suffixe et l'utilisent comme nom d'utilisateur. le pid comme suffixe et l'utilisent comme nom de fichier temporaire. Ce type de Ce type de schéma de nommage est prévisible et la condition de course qu'il crée est facile à gagner pour un attaquant. facile à gagner pour un attaquant. Une approche plus sûre, bien qu'encore inférieure, consiste à créer un répertoire temporaire en utilisant le nom du programme. est de créer un répertoire temporaire en utilisant le même schéma de nommage. Bien que Bien que cela permette de garantir qu'un fichier temporaire ne sera pas subverti, elle permet tout de même une simple attaque par déni de service. Pour Pour ces raisons, il est suggéré d'utiliser mktemp à la place.

Dans un script, j'invoque mktemp de la manière suivante

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")

qui crée un répertoire temporaire dans lequel je peux travailler, et dans lequel je peux nommer les fichiers réels de manière lisible et utile.

mktemp n'est pas standard, mais il existe sur de nombreuses plateformes. Les "X" seront généralement convertis en aléatoire, et d'autres seront probablement plus aléatoires ; cependant, certains systèmes (busybox ash, par exemple) limitent cet aléatoire de manière plus significative que d'autres.


À propos, la création sécurisée de fichiers temporaires n'est pas seulement importante pour les scripts shell. C'est pourquoi python dispose de fichier temporaire perl a Fichier::Temp ruby a Fichier temporaire etc

2 votes

L'option -t est obsolète : gnu.org/software/coreutils/manual/html_node/

7 votes

Il semble que ce soit le moyen le plus sûr et le plus multiplateforme d'utiliser mktemp est en combinaison avec basename comme suit mktemp -dt "$(basename $0). XXXXXXXXXX" . Si elle est utilisée sans basename vous pourriez obtenir une erreur comme celle-ci mktemp : modèle invalide, `/tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX', contient un séparateur de répertoire .

7 votes

Ignorez la faute de frappe (espace supplémentaire). mktemp -dt "$(basename $0).XXXXXXXXXX" est la voie correcte.

51voto

Paulpro Points 54844

Oui, utilisez mktemp .

Il créera un fichier temporaire dans un dossier conçu pour stocker des fichiers temporaires et vous garantira un nom unique. Elle produit le nom de ce fichier :

> mktemp
/tmp/tmp.xx4mM3ePQY
>

19voto

John Lawrence Points 1719

Vous pouvez consulter mktemp

L'utilitaire mktemp prend le modèle de nom de fichier donné et remplace une partie partie de celui-ci pour créer un nom de fichier unique. Le modèle peut être n'importe quel nom de fichier avec un certain nombre de 'X' ajoutés, par exemple /tmp/tfile.XXXXXXXXXX. Les 'X' de fin de fichier sont remplacés par une combinaison du numéro du processus en cours et de lettres aléatoires.

Pour plus de détails : man mktemp

12voto

kenorb Points 2464

Y a-t-il un avantage à créer un fichier temporaire d'une manière plus prudente ?

Les fichiers temporaires sont généralement créés dans le répertoire temporaire (tel que /tmp ) où tous les autres utilisateurs et processus ont un accès en lecture et en écriture (tout autre script peut y créer les nouveaux fichiers). Par conséquent, le script doit faire attention à la création des fichiers tels que l'utilisation avec les bonnes permissions (par exemple, lecture seule pour le propriétaire, voir : help umask ) et le nom du fichier ne doit pas être facile à deviner (idéalement, il doit être aléatoire). Sinon, si les noms de fichiers ne sont pas uniques, cela peut créer un conflit avec le même script exécuté plusieurs fois (ex. condition de course ) ou un attaquant pourrait soit détourner certaines informations sensibles (par exemple, lorsque les autorisations sont trop ouvertes et que le nom du fichier est facile à deviner), soit créer/remplacer le fichier avec sa propre version du code (comme remplacer les commandes ou les requêtes SQL en fonction de ce qui est stocké).


Vous pouvez utiliser l'approche suivante pour créer le répertoire temporaire :

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"

ou un fichier temporaire :

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"

Cependant, elle reste prévisible et n'est pas considérée comme sûre.

Conformément à man mktemp on peut lire :

Traditionnellement, de nombreux scripts shell prennent le nom du programme avec le pid comme suffixe et l'utilisent comme nom de fichier temporaire. Ce type de schéma de dénomination est prévisible et la condition de course qu'il crée est facile à gagner pour un attaquant.

Donc, pour être sûr, il est recommandé d'utiliser mktemp pour créer un fichier ou un répertoire temporaire unique ( -d ).

3 votes

Cela améliore en effet la réponse. Mon vote positif était déjà le vôtre, cependant. Je ne peux pas voter plus. Une suggestion que j'ai faite est d'expliquer ce que ${0##*/} et $$ ou un lien vers une documentation à ce sujet.

8voto

Barry Jones Points 474

mktemp est probablement le plus polyvalent, surtout si vous prévoyez de travailler avec le fichier pendant un certain temps.

Vous pouvez également utiliser un opérateur de substitution de processus <() si vous n'avez besoin du fichier que temporairement comme entrée pour une autre commande, par exemple :

$ diff <(echo hello world) <(echo foo bar)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X