web-dev-qa-db-fra.com

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

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 que le programme avait échoué parce qu'ils n'avaient pas un accès approprié à/tmp. Mais si j'ai enregistré ces fichiers dans le répertoire de travail, ces utilisateurs se sont également plaints de ne pas vouloir voir ces fichiers mystérieux.

Laquelle est une meilleure pratique? Dois-je insister pour que l'enregistrement sur /tmp est la bonne approche et défend tout échec comme "fonctionnant comme prévu" (c'est-à-dire demander à votre administrateur l'autorisation/l'accès approprié)?

79
HelloWorld

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 seraient uniques .

  • La plupart des logiciels de sauvegarde connaissent les répertoires contenant les fichiers temporaires et les ignorent. Si vous utilisez le répertoire en cours, 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 en RAM, ce qui rend l'accès en lecture-écriture beaucoup, beaucoup plus rapide .

  • Les fichiers temporaires sont souvent supprimés lors du redémarrage (s'ils sont dans un disque virtuel, ils sont 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 d'application et d'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 pour certaines API, frameworks et applications sont terribles , ce qui signifie que vous pouvez facilement atteindre cette limite si le répertoire actuel est déjà profondément dans la hiérarchie de l'arborescence et les noms de votre les fichiers temporaires sont trop longs.

  • Sur les serveurs, la surveillance de la croissance du répertoire temporaire se fait souvent immédiatement. Si vous utilisez un répertoire différent, il peut ne pas être surveillé, et surveiller tout le disque n'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 /tmp ou C:\Windows\temp Devrait être utilisé; ainsi, en accédant directement à ces répertoires, vous pouvez en effet 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; c'était déjà expliqué par Blrfl . C'est à l'administrateur système de configurer la machine; vous n'avez pas à modifier votre application.

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

  • Bash:

    # 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:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    ...
    char temp_file[] = "/tmp/tmp.XXXXXX";
    int fd = mkstemp(temp_file);
    dprintf(fd, "Hello World!!!\n");
    close(fd);
    
  • 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, comme dans PHP et Ruby, le fichier est supprimé lorsque le handle est fermé. C'est un avantage supplémentaire de l'utilisation des bibliothèques fournies avec le langage/framework.

141
Arseni Mourzenko

Dois-je insister pour que l'enregistrement dans/tmp soit la bonne approche et défendre tout échec comme "fonctionnant comme prévu" (c'est-à-dire demander à votre administrateur l'autorisation d'accès appropriée)?

Il existe des normes pour cela, et la meilleure chose que vous puissiez faire est de vous y conformer.

POSIX, qui est suivi par à peu près tous les systèmes d'exploitation non centraux de toute importance que vous êtes susceptible de rencontrer, a des dispositions pour créer des fichiers temporaires de nom unique dans un répertoire en utilisant des valeurs par défaut qui peuvent être reconfigurées par l'environnement:

  • L'en-tête C stdio.h Peut éventuellement inclure une macro P_tmpdir Qui nomme le répertoire temporaire du système.
  • TMPDIR est la variable d'environnement canonique pour changer l'emplacement des fichiers temporaires. Avant POSIX, il y avait d'autres variables utilisées, donc j'ai tendance à aller avec la première ou TMP, TEMPDIR et TEMP qui a une valeur, punting et utilisant le système par défaut s'il n'en existe aucun.
  • Les fonctions mkstemp() et tempfile() généreront des fichiers temporaires uniques.

Si vos utilisateurs se voient refuser la possibilité de créer des fichiers temporaires, le système est soit mal configuré, soit les administrateurs ne précisent pas quelle est leur politique sur de telles choses. Dans ces cas, vous seriez sur un terrain très ferme en disant que votre programme est conforme à une norme de portabilité bien établie et que son comportement peut être modifié en utilisant les variables d'environnement spécifiées par la norme.

33
Blrfl

Les réponses précédentes, bien que correctes, ne sont pas valables pour la plupart des clusters 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 est inutile d'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. Non seulement cela est lent, mais cela charge également le système pour le reste des utilisateurs, vous ne devez donc pas l'utiliser à moins que vous n'écriviez beaucoup et que vous puissiez vous en remettre si le travail se bloque.

Les nœuds de calcul ont leur propre disque dur, c'est-à-dire le système de fichiers le plus rapide disponible, et ce que vous devez utiliser. La documentation du cluster doit vous dire de quoi il s'agit, généralement /scratch, /tmp/[jobid], ou une variable d'environnement non standard ($SNIC_TMP dans 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 assurez-vous d'émettre un gros avertissement de graisse.

Edit: J'ajouterai une autre raison pour la forcer à être définie par l'utilisateur. Un de mes clusters a $TMPDIR mis à /scratch, accessible en écriture par l'utilisateur et sur le disque dur local. Mais, 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 faites confiance à $TMPDIR, vous rencontrerez des plantages aléatoires, très difficiles à déboguer. Vous pouvez donc accepter $TMPDIR, mais ne lui faites pas confiance.

Certains autres clusters ont cette variable correctement configurée, vous pouvez donc ajouter une option pour approuver explicitement $TMPDIR, sinon, émet un gros et gros avertissement.

9
Davidmh

Le répertoire de fichiers temporaires dépend fortement du système d'exploitation/de l'environnement. Par exemple, un répertoire web-servers-temp est distinct du répertoire os-temp-dir pour des raisons de sécurité.

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

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

9
k3b

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

Notez cependant que $XDG_RUNTIME_DIR est un nouvel ajout et il n'y a pas de solution de rechange standard pour les anciens systèmes en raison de problèmes de sécurité.

Si aucun de ces éléments ne convient, alors /tmp est le bon endroit. Vous ne devez jamais supposer que le répertoire courant est accessible en écriture.

1
o11c

ils n'avaient pas un accès approprié à/tmp

Ce que vous entendez par "accès approprié" n'est pas évident. Est-ce quelque chose comme /tmp/xxx: Permission denied?

Comme d'autres l'ont souligné, tout ce qui se trouve sous /tmp doit avoir un nom unique, donc si le programme utilise un fichier appelé /tmp/xxx pour chaque utilisateur, seul le premier utilisateur pourra l'utiliser. Le programme échouera pour tout le monde car ils essaient d'écrire dans un fichier appartenant à ce premier utilisateur.

Mais, quelque chose qui n'est mentionné dans aucune des autres réponses jusqu'à présent, il y a une bonne raison technique d'utiliser /tmp plutôt que /var/tmp, son répertoire personnel ou le répertoire courant.

Certains systèmes ont /tmp configuré comme un disque RAM, qui présente trois avantages principaux:

  • Un disque RAM sera beaucoup plus rapide que n'importe quoi sur un périphérique de stockage permanent.
  • Un disque RAM n'endommagera pas la mémoire SSD, ce qui limite le nombre d'écritures qu'il peut gérer au cours de sa vie.
  • Les fichiers temporaires seront automatiquement supprimés même si le programme qui les a créés se termine sans nettoyage après lui-même. (Également vrai pour /var/tmp, qui ne peut pas être un disque RAM.)
0
Ray Butterworth