Sollten temporäre Dateien in / tmp oder im aktuellen Arbeitsverzeichnis gespeichert werden?

76

Ich habe ein Programm, das temporäre Dateien erzeugen muss. Es ist für Cluster-Computer geschrieben.

Wenn ich diese Dateien in einem systemweiten temporären Verzeichnis (z. B.:) gespeichert habe /tmp, haben sich einige Benutzer beschwert, dass das Programm fehlgeschlagen ist, weil sie keinen ordnungsgemäßen Zugriff auf / tmp hatten. Aber wenn ich diese Dateien im Arbeitsverzeichnis speicherte, beschwerten sich diese Benutzer auch, dass sie diese mysteriösen Dateien nicht sehen wollten.

Welches ist eine bessere Praxis? Sollte ich darauf bestehen, dass das Speichern unter /tmpdie richtige Vorgehensweise ist, und alle Fehler als "bestimmungsgemäß funktionieren" verteidigen (dh Ihren Administrator nach der richtigen Erlaubnis / dem richtigen Zugriff fragen)?

Kleinschach
quelle
3
überprüfen , ob das Programm Zugriff hat und wenn nicht ein anderes temporäres Verzeichnis finden
Ratsche Freak
24
Wenn Ihr Administrator die Zugriffsrechte vermasselt hat, sollte er dies definitiv beheben. Was würden Sie tun, wenn Ihr Administrator vergessen hätte, Ihrem Programm Ausführungsrechte hinzuzufügen?
Doc Brown
7
Sie werden / tmp auf den meisten Windows-Systemen nicht finden, aber es gibt einen OS-Aufruf, der Ihnen sagt, wo Sie temporäre Dateien ablegen sollen.
Ian
28
Wenn einige /tmpBenutzer auf einem Unix-ähnlichen System keinen Zugriff hatten , ist es falsch konfiguriert. Der Superuser sollte so etwas tun chmod 1777 /tmp.
Musiphil
12
Beachten Sie, dass $ TMPDIR möglicherweise auf einen anderen Pfad verweist als /tmp/, den Sie stattdessen verwenden sollten. Siehe einige der Antworten;)
Marcelm

Antworten:

141

Temporäre Dateien müssen aus verschiedenen Gründen im temporären Verzeichnis des Betriebssystems gespeichert werden:

  • Das Betriebssystem macht es sehr einfach, diese Dateien zu erstellen und gleichzeitig sicherzustellen, dass ihre Namen eindeutig sind .

  • Die meisten Sicherungsprogramme kennen die Verzeichnisse mit den temporären Dateien und überspringen diese. Wenn Sie das aktuelle Verzeichnis verwenden, kann dies wichtige Auswirkungen auf die Größe inkrementeller Sicherungen haben, wenn Sicherungen häufig durchgeführt werden.

  • Das temporäre Verzeichnis befindet sich möglicherweise auf einer anderen Festplatte oder im RAM, wodurch der Lese- / Schreibzugriff erheblich beschleunigt wird .

  • Temporäre Dateien werden häufig während des Neustarts gelöscht (wenn sie sich auf einer Ramdisk befinden, gehen sie einfach verloren). Dies verringert das Risiko eines unendlichen Wachstums, wenn Ihre App die temporären Dateien nicht immer korrekt entfernt (zum Beispiel nach einem Absturz).

    Das Bereinigen von temporären Dateien aus dem Arbeitsverzeichnis kann leicht zu Problemen führen, wenn die Dateien zusammen mit Anwendungs- und Benutzerdateien gespeichert werden. Sie können dieses Problem abmildern, indem Sie ein separates Verzeichnis im aktuellen Verzeichnis erstellen. Dies kann jedoch zu einem anderen Problem führen:

  • Auf einigen Plattformen ist die Pfadlänge möglicherweise zu lang. Beispielsweise sind unter Windows die Pfadbeschränkungen für einige APIs, Frameworks und Anwendungen schrecklich . Dies bedeutet, dass Sie diese Grenze leicht überschreiten können, wenn sich das aktuelle Verzeichnis bereits tief in der Baumstruktur befindet und die Namen Ihrer temporären Dateien zu lang sind.

  • Auf Servern wird das Wachstum des temporären Verzeichnisses häufig sofort überwacht . Wenn Sie ein anderes Verzeichnis verwenden, wird es möglicherweise nicht überwacht, und die Überwachung der gesamten Festplatte hilft nicht leicht herauszufinden, dass es die temporären Dateien sind, die immer mehr Platz einnehmen.

Vergewissern Sie sich, dass das Betriebssystem eine temporäre Datei für die Zugriffsverweigerungsfehler erstellt. Das Betriebssystem kann zum Beispiel wissen, dass für einen bestimmten Benutzer ein anderes Verzeichnis als /tmpoder C:\Windows\tempverwendet werden sollte; Wenn Sie also direkt auf diese Verzeichnisse zugreifen, kann es tatsächlich zu einem Fehler kommen, bei dem der Zugriff verweigert wird.

Wenn Ihnen der Zugriff verweigert wird, obwohl Sie den Betriebssystemaufruf verwenden, bedeutet dies einfach, dass der Computer schlecht konfiguriert wurde. Dies wurde bereits von Blrfl erklärt . Es ist Aufgabe des Systemadministrators, den Computer zu konfigurieren. Sie müssen Ihre Bewerbung nicht ändern.

Das Erstellen temporärer Dateien ist in vielen Sprachen unkompliziert. Einige Beispiele:

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

    // 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);
  • Rubin:

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

Beachten Sie, dass in einigen Fällen, z. B. in PHP und Ruby, die Datei entfernt wird, wenn das Handle geschlossen wird. Dies ist ein zusätzlicher Vorteil der Verwendung der mit der Sprache / dem Framework gebündelten Bibliotheken.

Arseni Mourzenko
quelle
2
Was meinen Sie mit "Stellen Sie sicher, dass das Betriebssystem eine temporäre Datei für Sie erstellt"? Also fopen("/tmp/mytmpfile", "w");sollte ich statt zB einen Systemaufruf machen, um temporäre Dateien zu verarbeiten?
Simon
30
@gurka: Sie sollten anrufen tmpfile(3), um Ihre temporären Dateien zu generieren, oder zumindest, mktemp(3)um die Dateinamen zu erstellen.
TMN
3
@TMN: Es handelt sich nur um Bibliotheksfunktionen, die im Benutzerbereich ausgeführt werden, und sie haben keine Magie, um den vom Betriebssystem angegebenen Berechtigungsfehler zu umgehen.
Musiphil
25
@musiphil Sowohl tmpfile als auch mktemp verwenden externe Variablen, um den Pfad für temporäre Dateien zu bestimmen. Diese wurden möglicherweise so eingerichtet, dass sie auf ein anderes Verzeichnis als / tmp / verweisen, möglicherweise auf ein Benutzerverzeichnis. Der Versuch, einen Dateinamen manuell in / tmp / zu erstellen, schlägt möglicherweise fehl, während tmpfile und mktemp gültige Pfade zurückgeben würden.
Rohr
2
@musiphil: Ich habe nie gesagt, dass sie das Berechtigungsproblem beheben würden. Ich habe auf seine Frage geantwortet, ob Systemaufrufe zum Erstellen der Dateien verwendet werden sollen.
TMN
33

Sollte ich darauf bestehen, dass das Speichern in / tmp der richtige Ansatz ist, und mich gegen einen Fehler als "bestimmungsgemäß funktionierend" verteidigen (dh Ihren Administrator nach dem richtigen Berechtigungszugriff fragen)?

Es gibt Standards dafür, und das Beste, was Sie tun können, ist, sie einzuhalten.

POSIX, auf das so gut wie jedes Nicht-Mainframe-Betriebssystem von beliebiger Bedeutung folgt, verfügt über Vorkehrungen zum Erstellen eindeutig benannter temporärer Dateien in einem Verzeichnis unter Verwendung von Standardwerten, die von der Umgebung neu konfiguriert werden können:

  • Der C- stdio.hHeader kann optional ein P_tmpdirMakro enthalten, das das temporäre Verzeichnis des Systems benennt.
  • TMPDIRist die kanonische Umgebungsvariable zum Ändern des Speicherorts temporärer Dateien. Vor POSIX wurden andere Variablen verwendet, daher tendiere ich dazu, die erste davon zu verwenden, oder TMP- TEMPDIRund TEMPdas hat einen Wert - die Standardeinstellung des Systems zu verwenden, wenn keine vorhanden ist.
  • Mit den Funktionen mkstemp()und tempfile()werden eindeutige temporäre Dateien generiert.

Wenn Ihren Benutzern die Möglichkeit verweigert wird, temporäre Dateien zu erstellen, ist das System entweder falsch konfiguriert oder die Administratoren stellen nicht klar, welche Richtlinien diesbezüglich gelten. In diesen Fällen können Sie mit Bestimmtheit sagen, dass Ihr Programm einem etablierten Portabilitätsstandard entspricht und dass sein Verhalten mithilfe der vom Standard angegebenen Umgebungsvariablen geändert werden kann.

Blrfl
quelle
P_tmpdirist kein Teil von stdio.him Sinne der C-Sprachspezifikation. Es kann durch POSIX oder SVID definiert werden.
Musiphil
1
@musiphil: Wie aus der (jetzt geklärten) Antwort hervorgeht, ist es Teil von POSIX. (Technisch gesehen handelt es sich um eine X / Open- Systemerweiterung , die von POSIX integriert wurde. Siehe pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Stimme voll und ganz den obigen Aussagen zu. Ein gutes Beispiel sind Linux-Systeme mit pam_tmpdir- dies setzt TMPDIRund TMPfür jeden Benutzer anders zu sein, für Robustheit und Datenschutz. Es ist auch nützlich, TMPDIReinen einzelnen Befehl festlegen zu können. Wenn Sie Ihr übliches temporäres Verzeichnis aus Gründen der Geschwindigkeit in einem RAM-Dateisystem haben, müssen Sie dies möglicherweise für Befehle ausführen, die große temporäre Dateien generieren (z. B. einen Riesen sort). Ignorieren Sie nicht die Standards / Konventionen, die Ihre Benutzer erwarten!
Toby Speight
Überprüfen Sie auf jeden Fall die Umgebung auf den Speicherort temporärer Dateien und niemals auf Hardcode / tmp. Da bei einem freigegebenen tmp Sicherheitsprobleme auftreten, habe ich oft gesehen, dass es sich um das Erstellen von Verzeichnissen pro Benutzer / tmp ohne Lese- / Schreibberechtigung für andere Personen handelt. Es entfernt mögliche Rennbedingungen und Symlink-Angriffe.
Zan Lynx
9

Das temporäre Dateiverzeichnis ist stark vom Betriebssystem / der Umgebung abhängig. Zum Beispiel ist ein temporäres Verzeichnis des Webservers aus Sicherheitsgründen vom temporären Verzeichnis des Betriebssystems getrennt.

Unter MS-Windows hat jeder Benutzer ein eigenes Temp-Verzeichnis.

Sie sollten hierfür createTempFile () verwenden, wenn eine solche Funktion verfügbar ist.

k3b
quelle
1
Denken Sie nur an versteckte Betriebssystemeinschränkungen in Windows. Wir haben festgestellt, dass die maximale Anzahl von Dateien in einem Ordner auf 65.565 begrenzt ist. Sicher, das ist eine Menge von Dateien, und sicher, sollten Sie nie denkbar , dass viele rumliegen. Aber sind Sie sicher, dass jede App pünktlich und korrekt aufräumt?
Mike Hofer
Ah, ich habe deinen Kommentar zu spät gesehen. Ich habe gerade dasselbe geschrieben. Übrigens ist das Limit hauptsächlich auf die Mechanik der Funktion GetTimeFileName () zurückzuführen, nicht auf NTFS. Diese von Ihnen angegebene Ordnerbeschränkung gilt nur für FAT32 .
JensG
9

Die vorherigen Antworten sind zwar korrekt, gelten jedoch nicht für die meisten großen Computercluster.

Computercluster folgen nicht immer den Standardkonventionen für Computer, normalerweise aus guten Gründen, und es macht keinen Sinn, dies mit den Systemadministratoren zu besprechen.

Ihr aktuelles Verzeichnis bezieht sich auf das zentrale Dateisystem, auf das über das Netzwerk zugegriffen wird. Dies ist nicht nur langsam, sondern belastet auch das System für den Rest der Benutzer. Sie sollten es daher nicht verwenden, es sei denn, Sie schreiben nicht viel und Sie können es wiederherstellen, wenn der Job abstürzt.

Die Rechenknoten verfügen über eine eigene Festplatte, das ist das schnellste verfügbare Dateisystem, und was Sie verwenden sollten. In der Cluster-Dokumentation sollte angegeben werden, um was es sich in der Regel /scratchhandelt /tmp/[jobid]oder um eine nicht standardmäßige Umgebungsvariable ( $SNIC_TMPin einer der von mir verwendeten).

Also, was ich empfehle, ist es benutzerkonfigurierbar zu machen. Die Standardeinstellungen können die ersten sein, auf die Sie Schreibzugriff haben:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Erwarten Sie bei diesem Ansatz jedoch eine geringe Erfolgsquote und geben Sie eine große Fettwarnung aus.

Bearbeiten: Ich werde einen weiteren Grund hinzufügen, um die Benutzereinstellung zu erzwingen. Einer meiner Cluster ist $TMPDIRauf " /scratchVom Benutzer beschreibbar" und auf der lokalen Festplatte eingestellt. Die Dokumentation besagt jedoch, dass alles, was Sie außerhalb von schreiben, /scratch/[jobid]jederzeit gelöscht werden kann, selbst mitten in der Ausführung. Wenn Sie sich also an die Standards halten und vertrauen $TMPDIR, stoßen Sie auf zufällige Abstürze, die sich nur schwer debuggen lassen. Sie können es also akzeptieren $TMPDIR, aber nicht vertrauen.

Bei einigen anderen Clustern ist diese Variable ordnungsgemäß konfiguriert, sodass Sie eine Option hinzufügen können, um explizit zu vertrauen $TMPDIR. Andernfalls wird eine große, fette Warnung ausgegeben.

Davidmh
quelle
1
Welche sind genau die vorherigen Antworten?
Tulains Córdova
2
Was Sie hier sagen, ist, dass bei einigen Clustern, die sich nicht an einen allgemein anerkannten Standard halten, um Programmen mitzuteilen, wo sie ihre temporären Dateien schreiben sollen, pro Programm eine zusätzliche clusterspezifische Anpassung erforderlich ist. Ziemlich schwacher Tee, wenn du mich fragst.
Blrfl
@Blrfl Sie können die Standards so oft winken lassen, wie Sie möchten, und Code schreiben, der perfekt zu ihnen passt und immer abstürzt. Sie können versuchen, mit den Sysadmins jedes von Ihnen verwendeten Clusters zu kämpfen. oder Sie können Ihren Glauben annehmen und ihn konfigurierbar machen. Außerdem muss man in HPC den Code normalerweise ohnehin an die Besonderheiten des Clusters anpassen (verfügbarer RAM, relative Geschwindigkeit der Dateisysteme, MPI-Implementierung, allgemeine Verfügbarkeit von Ressourcen ...), es gibt keine "Einheitsgröße".
Davidmh
@ Davidmh: Verstanden, aber nicht der Punkt. Der Standard macht es auf nicht überraschende Weise konfigurierbar . Wenn ich bekanntermaßen konformen Code in einen Cluster bringe, in dem der Standard nicht eingehalten wird, muss ich ihn genau an einer Stelle festlegen , z. B. am Einstiegspunkt. Das ist eine Sache weniger im Rest des Codes, um zu prüfen, zu modifizieren und zu riskieren, falsch zu werden.
Blrfl
1

Bei vielen Anwendungen sollten Sie in Erwägung ziehen, temporäre Dateien in $XDG_RUNTIME_DIRoder zu speichern $XDG_CACHE_HOME(die anderen XDG-Verzeichnisse gelten für nicht temporäre Dateien). Anweisungen zu deren Berechnung, wenn sie nicht explizit in der Umgebung übergeben werden, finden Sie in der XDG-basierten Spezifikation oder in einer Bibliothek, die diesen Teil bereits implementiert.

Beachten Sie jedoch, dass dies $XDG_RUNTIME_DIReine Neuerung ist und es aus Sicherheitsgründen keinen Standard-Fallback für ältere Systeme gibt.

Wenn beides nicht passt, /tmpist es der richtige Ort. Sie sollten niemals davon ausgehen, dass das aktuelle Verzeichnis beschreibbar ist.

o11c
quelle
-2

Dies ist eher eine Alternative, aber Sie können die Verknüpfung () der Datei sofort nach fopen () aufheben. Es kommt auf das Nutzungsverhalten an.

Das Aufheben der Verknüpfung der Dateien kann auf verschiedene Arten erfolgen:

  • Datei wird nicht gesehen - Benutzer sieht sie nicht.
  • Datei wird von anderen Prozessen nicht gesehen - es besteht keine Chance, dass ein anderer Prozess die Datei versehentlich ändert.
  • einfache Bereinigung bei Programmabsturz.

Dateien müssen in / tmp erstellt werden. Wenn der Benutzer keine Rechte hat, um dort eine Datei zu erstellen, bedeutet dies, dass das System falsch konfiguriert ist.

Dateien können nicht im Home-Verzeichnis des Benutzers erstellt werden. Viele Benutzer, wie "nobody", "www-data" und viele andere, haben keine Rechte, in ihre Home-Verzeichnisse zu schreiben, oder sie sind sogar chroot () - ed. Beachten Sie, dass selbst in der Chroot-Umgebung / tmp noch vorhanden ist.

Nick
quelle
Dies ist zwar im Allgemeinen eine gute Idee, hilft aber nicht den Benutzern, die keine Schreibrechte für das Verzeichnis haben, in dem die Datei erstellt werden soll.
5gon12eder
4
Es beantwortet auch nicht die Frage, wo temporäre Dateien abgelegt werden sollen.
Blrfl
Ich glaube, meine Antwort ist irgendwie wichtig. Ich habe editiert, wahrscheinlich ist das klarer.
Nick