Les fichiers temporaires doivent-ils être enregistrés dans / tmp ou dans le répertoire de travail actuel?

76

J'ai un programme qui doit générer des fichiers temporaires. Il est écrit pour les machines en cluster.

Si j'ai enregistré ces fichiers dans un répertoire temporaire à l'échelle du système (par exemple:) /tmp, certains utilisateurs se sont plaints du fait que le programme avait échoué car ils ne disposaient pas d'un accès approprié à / tmp. Mais si je sauvegardais ces fichiers dans le répertoire de travail, ces utilisateurs se plaignaient également de ne pas vouloir voir ces fichiers mystérieux.

Lequel est une meilleure pratique? Devrais-je insister sur le fait que l’épargne /tmpest la bonne approche et défendre tout échec comme "fonctionnant comme prévu" (c’est-à-dire demander à votre administrateur l’autorisation / le droit de visite requis)?

Petitchess
la source
3
Vérifiez si le programme est accessible et si ce n’est pas le cas, trouvez un autre répertoire temporaire
Ratchet Freak
24
Si votre administrateur a gâché les droits d'accès, il devrait certainement le réparer. Que feriez-vous si votre administrateur oubliait d'ajouter des droits d'exécution à votre programme?
Doc Brown
7
Vous ne trouverez pas / tmp sur la plupart des systèmes Windows, mais un appel de système d’exploitation vous indiquera où placer les fichiers temporaires.
Ian
28
Si certaines personnes n’ont pas accès à /tmpun système de type Unix, il est mal configuré. Le superutilisateur devrait faire quelque chose comme chmod 1777 /tmp.
musiphil
12
Attention, $ TMPDIR peut indiquer un chemin différent de celui /tmp/que vous devriez utiliser à la place. Voir quelques réponses;)
marcelm

Réponses:

141

Les fichiers temporaires doivent être stockés dans le répertoire temporaire du système d'exploitation pour plusieurs raisons:

  • Le système d'exploitation facilite la création de ces fichiers tout en garantissant que leurs noms sont uniques .

  • La plupart des logiciels de sauvegarde savent quels sont les répertoires contenant les fichiers temporaires et les ignorent. Si vous utilisez le répertoire actuel, cela pourrait avoir un effet important sur la taille des sauvegardes incrémentielles si les sauvegardes sont effectuées fréquemment.

  • Le répertoire temporaire peut se trouver sur un autre disque ou dans la RAM, ce qui rend l’ accès en lecture-écriture beaucoup plus rapide .

  • Les fichiers temporaires sont souvent supprimés lors du redémarrage (s’ils se trouvent dans un disque mémoire, ils sont tout simplement perdus). Cela réduit le risque de croissance infinie si votre application ne supprime pas toujours correctement les fichiers temporaires (par exemple, après un crash).

    Le nettoyage des fichiers temporaires du répertoire de travail peut facilement devenir compliqué si les fichiers sont stockés avec les fichiers de l'application et de l'utilisateur. Vous pouvez atténuer ce problème en créant un répertoire distinct dans le répertoire actuel, mais cela pourrait entraîner un autre problème:

  • La longueur du chemin peut être trop longue sur certaines plates-formes. Par exemple, sous Windows, les limites de chemin d'accès pour certaines API, structures et applications sont terribles , ce qui signifie que vous pouvez facilement atteindre cette limite si le répertoire en cours se trouve déjà dans la hiérarchie de l'arborescence et que les noms de vos fichiers temporaires sont trop longs.

  • Sur les serveurs, le suivi de la croissance du répertoire temporaire est souvent effectué immédiatement. Si vous utilisez un répertoire différent, il se peut que celui-ci ne soit pas surveillé, et surveiller l'ensemble du disque ne vous aidera pas à comprendre facilement que ce sont les fichiers temporaires qui prennent de plus en plus de place.

En ce qui concerne les erreurs d'accès refusé, assurez-vous de laisser le système d'exploitation créer un fichier temporaire pour vous. Le système d'exploitation peut par exemple savoir que, pour un utilisateur donné, un répertoire autre que /tmpou C:\Windows\tempdevrait être utilisé; ainsi, en accédant directement à ces répertoires, vous risquez peut-être de rencontrer une erreur d’accès refusé.

Si vous obtenez un accès refusé même lorsque vous utilisez l'appel du système d'exploitation, eh bien, cela signifie simplement que la machine a été mal configurée; cela a déjà été expliqué par Blrfl . C'est à l'administrateur système de configurer la machine. vous n'êtes pas obligé de changer votre application.

La création de fichiers temporaires est simple dans de nombreuses langues. Quelques exemples:

  • Frapper:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
  • Python:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
  • C #:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
  • Rubis:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close

Notez que dans certains cas, tels que PHP et Ruby, le fichier est supprimé lorsque le descripteur est fermé. C'est un avantage supplémentaire d'utiliser les bibliothèques fournies avec le langage / framework.

Arseni Mourzenko
la source
2
Qu'entendez-vous par "assurez-vous de laisser le système d'exploitation créer un fichier temporaire pour vous"? Donc, au lieu de, par exemple, fopen("/tmp/mytmpfile", "w");je devrais faire un appel système pour gérer les fichiers temporaires?
simon
30
@gurka: Vous devriez appeler tmpfile(3)pour générer vos fichiers temporaires, ou au moins appeler mktemp(3)pour créer les noms de fichiers.
TMN
3
@TMN: Ce ne sont que des fonctions de bibliothèque qui s'exécutent dans l'espace utilisateur et n'ont pas de magie pour contourner l'erreur d'autorisation donnée par le système d'exploitation.
musiphil
25
@musiphil tmpfile et mktemp utilisent des variables externes pour déterminer le chemin d'accès aux fichiers temporaires. Ceux-ci peuvent avoir été configurés pour pointer vers un autre répertoire que / tmp /, peut-être un répertoire par utilisateur. Essayer de créer manuellement un nom de fichier dans / tmp / peut échouer, alors que tmpfile et mktemp renverraient des chemins valides.
pipe
2
@musiphil: Je n'ai jamais dit qu'ils régleraient le problème des autorisations, je répondais à sa question sur l'utilisation d'appels système pour créer les fichiers.
TMN
33

Devrais-je insister pour que sauver dans / tmp soit la bonne approche et défendre en cas d'échec "de fonctionner comme prévu" (c'est-à-dire demander à votre administrateur l'accès en tant que tel)?

Il existe des normes à cet égard et la meilleure chose à faire est de les respecter.

POSIX, qui est suivi par presque tous les systèmes d'exploitation autres que les ordinateurs centraux et présentant une importance particulière, comporte des dispositions permettant de créer des fichiers temporaires portant un nom unique dans un répertoire à l'aide de valeurs par défaut pouvant être reconfigurées par l'environnement:

  • L'en- stdio.htête C peut éventuellement inclure une P_tmpdirmacro qui nomme le répertoire temporaire du système.
  • TMPDIRest la variable d'environnement canonique permettant de modifier l'emplacement des fichiers temporaires. Avant POSIX, d'autres variables étaient utilisées. J'ai donc tendance à choisir la première de celles-ci ou TMP, TEMPDIRet TEMPqui a une valeur, le punting et l'utilisation de la valeur par défaut du système si aucune d'entre elles n'existe.
  • Les fonctions mkstemp()et tempfile()généreront des fichiers temporaires uniques.

Si la possibilité de créer des fichiers temporaires est refusée à vos utilisateurs, cela signifie que le système est mal configuré ou que les administrateurs ne précisent pas clairement quelle est leur stratégie. Dans ces cas, vous seriez sur des bases solides en affirmant que votre programme est conforme à une norme de portabilité bien établie et que son comportement peut être modifié à l'aide des variables d'environnement spécifiées par la norme.

Blrfl
la source
P_tmpdirne fait pas partie de stdio.hla définition de la spécification du langage C. Il peut être défini par POSIX ou SVID.
musiphil
1
@musiphil: Comme l'indique la réponse (maintenant clarifiée), cela fait partie de POSIX. (Techniquement, il est un X / Open extension système qui Posix incorporé Voir. Pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Entièrement d'accord avec tout ce qui précède. Un bon exemple est celui des systèmes Linux avec pam_tmpdir- cela définit TMPDIRet TMPdoit être différent pour chaque utilisateur, pour la robustesse et la confidentialité. Il est également utile de pouvoir définir TMPDIRune seule commande. Si votre répertoire temporaire habituel se trouve dans un système de fichiers RAM plus rapidement, vous devrez peut-être le faire pour les commandes générant d'énormes fichiers temporaires (comme un géant sort, par exemple). N'ignorez pas les normes / conventions auxquelles vos utilisateurs s'attendent!
Toby Speight
Vérifiez définitivement l'environnement de l'emplacement des fichiers temporaires et ne codez jamais dur / tmp. Comme un tmp partagé présente des problèmes de sécurité, une des solutions que j'ai souvent constatées consiste à créer des répertoires par utilisateur / tmp sans autorisation de lecture-écriture pour quiconque. Il supprime les conditions de concurrence possibles et les attaques par lien symbolique.
Zan Lynx
9

Le répertoire de fichier temporaire dépend fortement du système d'exploitation / de l'environnement. Par exemple, un répertoire Web-server-temp est séparé du répertoire os-temp-dir pour des raisons de sécurité.

Sous ms-windows, chaque utilisateur a son propre répertoire-temp.

vous devez utiliser createTempFile () pour cela si une telle fonction est disponible.

k3b
la source
1
N'oubliez pas les limitations cachées du système d'exploitation dans Windows. Nous avons découvert à nos dépens que le nombre maximal de fichiers d’un dossier est limité à 65 565. Bien sûr, c'est un grand nombre de fichiers, et bien sûr, vous ne devriez jamais imaginer avoir que beaucoup autour de la pose. Mais êtes-vous sûr que chaque application se nettoie de manière opportune et sage?
Mike Hofer
Ah, j'ai vu votre commentaire trop tard. Je viens d'écrire la même chose ci-dessus. BTW, la limite est principalement due aux mécanismes de la fonction GetTimeFileName (), pas à NTFS. La limite de dossiers que vous avez mentionnée ne s'applique qu'à FAT32 .
JensG
9

Les réponses précédentes, bien que correctes, ne sont pas valables pour la plupart des grappes d'ordinateurs à grande échelle.

Les clusters d’ordinateurs ne suivent pas toujours les conventions standard pour les machines, généralement pour de bonnes raisons, et il n’ya aucun intérêt à en discuter avec les administrateurs système.

Votre répertoire actuel fait référence au système de fichiers central, accessible via le réseau. Ce n'est pas seulement lent, mais cela charge également le système pour le reste des utilisateurs. Vous ne devez donc pas l'utiliser si vous n'écrivez pas beaucoup et vous pourrez le récupérer si le travail se bloque.

Les nœuds informatiques ont leur propre disque dur, le système de fichiers le plus rapide disponible, et ce que vous devriez utiliser. La documentation de cluster doit vous dire ce qu'il est, en général /scratch, /tmp/[jobid]ou une variable non enviroment standard ( $SNIC_TMPdans l' un de ceux que j'utilise).

Donc, ce que je recommande, c'est de le rendre configurable par l'utilisateur. Les valeurs par défaut peuvent être les premières auxquelles vous avez accès en écriture:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Mais attendez-vous à un faible taux de réussite avec cette approche et veillez à émettre un gros avertissement.

Edit: Je vais ajouter une autre raison pour le forcer à être défini par l'utilisateur. L'un de mes clusters est $TMPDIRdéfini sur /scratch, c'est-à-dire qu'il est accessible en écriture pour l'utilisateur et sur le disque dur local. Cependant, la documentation indique que tout ce que vous écrivez en dehors de /scratch/[jobid]peut être supprimé à tout moment, même au milieu de la course. Donc, si vous suivez les normes et que $TMPDIRvous faites confiance , vous rencontrerez des plantages aléatoires, très difficiles à déboguer. Donc, vous pouvez accepter $TMPDIR, mais ne pas y croire.

Dans certains autres clusters, cette variable est correctement configurée. Vous pouvez donc ajouter une option de confiance explicite $TMPDIR, sinon, émettez un gros avertissement.

Davidmh
la source
1
Quelles sont exactement les réponses précédentes?
Tulains Córdova
2
Donc, ce que vous dites, c’est que, parce que certaines grappes qui n’ont pas la tâche triviale d’adhérer à une norme bien établie pour indiquer aux programmes où écrire leurs fichiers temporaires, c’est une personnalisation supplémentaire spécifique à la grappe requise par programme. Assez faible thé si vous me demandez.
Blrfl
@Blrfl vous pouvez agiter les normes autant que vous le souhaitez, et écrire un code qui leur convient parfaitement et qui se bloque toujours; vous pouvez essayer de vous battre avec les administrateurs système de chaque cluster que vous utilisez; ou vous pouvez accepter votre foi et la rendre configurable. De plus, dans HPC, il est généralement nécessaire d’adapter le code aux spécificités du cluster (mémoire vive disponible, vitesse relative des systèmes de fichiers, implémentation MPI, disponibilité générale des ressources ...), il n’existe pas de solution unique.
Davidmh
@ Davidmh: Compris, mais pas le point. Le standard le rend configurable de manière non étonnante. Si je transfère du code conforme connu à un cluster dans lequel la norme n'est pas respectée, je dois le définir exactement au même endroit, par exemple au point d'entrée. C’est une chose de moins dans le reste du code à vérifier, modifier et risquer de se tromper.
Blrfl
1

Pour de nombreuses applications, vous devriez envisager de placer des fichiers temporaires dans $XDG_RUNTIME_DIRou $XDG_CACHE_HOME(les autres répertoires XDG sont destinés à des fichiers non temporaires). Pour obtenir des instructions sur leur calcul s'ils ne sont pas explicitement passés dans l'environnement, reportez-vous à la spécification basée sur XDG ou recherchez une bibliothèque qui implémente déjà cette partie.

Notez toutefois qu'il $XDG_RUNTIME_DIRs'agit d'un nouvel ajout et qu'il n'existe pas de solution de secours standard pour les systèmes plus anciens en raison de problèmes de sécurité.

Si aucune de ces options ne convient, /tmple lieu est correct. Vous ne devez jamais supposer que le répertoire en cours est accessible en écriture.

o11c
la source
-2

Cela ressemble plus à une alternative, mais vous pouvez aussi dissocier () le fichier immédiatement après fopen (). Cela dépend des habitudes d’utilisation des cours.

Le fait de dissocier les fichiers, s’il est possible de le faire, a plusieurs avantages:

  • le fichier n'est pas vu - l'utilisateur ne le voit pas.
  • le fichier n'est pas vu par d'autres processus - il n'y a aucune chance qu'un autre processus modifie le fichier par erreur.
  • nettoyage facile en cas de blocage du programme.

Les fichiers doivent être créés dans / tmp. Si l'utilisateur n'a pas le droit de créer un fichier, cela signifie que le système est mal configuré.

Les fichiers ne peuvent pas être créés dans le répertoire de base des utilisateurs. Beaucoup d'utilisateurs, tels que "personne", "www-data" et beaucoup d'autres, n'ont pas le droit d'écrire dans leurs répertoires personnels, ou sont même chrootés () - ed. Notez que même dans un environnement chroot / tmp existe toujours.

pseudo
la source
Bien que cela puisse être une bonne idée en général, cela n'aide pas les utilisateurs qui ne disposent pas des autorisations d'écriture sur le répertoire dans
lequel
4
Il ne répond pas non plus à la question, à savoir où placer les fichiers temporaires.
Blrfl
Je crois que ma réponse est en quelque sorte importante. J'ai édité, est probablement plus clair de cette façon.
Nick le