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é)?
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.
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:
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.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.
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.
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.
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.
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:
/var/tmp
, qui ne peut pas être un disque RAM.)