Finden des richtigen tmp-Verzeichnisses auf mehreren Plattformen

46

Ich habe ein Skript, das temporäre Dateien für seine Arbeit erstellen und nach sich selbst bereinigen muss. Meine Frage ist das Finden des richtigen Basisverzeichnisses für die temporären Dateien.

Das Skript muss auf mehreren Plattformen funktionieren: Git Bash (Windows), Solaris, Linux, OSX. Auf jeder Plattform wird das bevorzugte temporäre Verzeichnis unterschiedlich ausgedrückt:

  • Windows: %TMP%(und möglicherweise %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: Sollte es sein $TMPDIR, scheint aber auf mehreren Systemen, die ich ausprobiert habe, nicht eingestellt zu sein

Also habe ich in meinem Skript dieses Boilerplate hinzugefügt:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

Das scheint zu langweilig. Gibt es einen besseren Weg?

janos
quelle
6
Einfach ${TMPDIR-/tmp}auf Unix-Likes anwenden. TMPDIRGibt an (vom System oder Administrator oder Benutzer), wann Sie nicht /tmpfür temporäre Dateien verwenden sollen.
Stéphane Chazelas

Antworten:

72

Eine etwas portablere Möglichkeit, mit temporären Dateien umzugehen, ist die Verwendung von mktemp. Es werden temporäre Dateien erstellt und ihre Pfade für Sie zurückgegeben. Zum Beispiel:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

Sie können es ganz einfach in einem Skript verwenden:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

Wenn Sie die Manpage lesen, sollten Sie in der Lage sein, Optionen gemäß Ihren Anforderungen festzulegen. Zum Beispiel:

  • -d Erstellt ein Verzeichnis anstelle einer Datei.
  • -u erzeugt einen Namen, erzeugt aber nichts.

Mit können -uSie das temporäre Verzeichnis ganz einfach abrufen mit ...

$ tmpdir=$(dirname $(mktemp -u))

Weitere Informationen zu finden Sie mktemphier .

Bearbeiten in Bezug auf Mac OS X: Ich habe noch nie ein Mac OS X- System verwendet, aber laut einem Kommentar von Tyilo scheint es, alsmktemp müssten Sie für Mac OS X eine Vorlage bereitstellen (ein optionales Argument unter Linux). Zitat:

Die Vorlage kann ein beliebiger Dateiname sein, an den beispielsweise eine Anzahl von "X" angehängt ist /tmp/temp.XXXX. Die nachfolgenden "X" werden durch die aktuelle Prozessnummer und / oder eine eindeutige Buchstabenkombination ersetzt. Die Anzahl der eindeutigen Dateinamen, die mktemp zurückgeben kann, hängt von der Anzahl der bereitgestellten "Xs" ab. Sechs "X" führen dazu, dass mktemp 1 von 56800235584 (62 ** 6) möglichen Dateinamen auswählt.

Die Manpage sagt auch, dass diese Implementierung von der OpenBSD-Manpage für inspiriert ist mktemp. Eine ähnliche Divergenz könnte daher von OpenBSD und FreeBSD - Benutzer als auch (siehe beachten History Abschnitt).

Wie Sie wahrscheinlich bemerkt haben, müssen Sie dazu einen vollständigen Dateipfad angeben, einschließlich des temporären Verzeichnisses, nach dem Sie in Ihrer Frage suchen. Dieses kleine Problem kann mit dem -tSchalter behandelt werden . Während diese Option anscheinend ein Argument ( prefix) erfordert, scheint sie mktempsich $TMPDIRbei Bedarf darauf zu verlassen.

Alles in allem sollten Sie in der Lage sein, mit ... dasselbe Ergebnis wie oben zu erzielen.

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Für Feedback von Mac OS X-Benutzern wäre ich sehr dankbar, da ich diese Lösung nicht selbst testen kann.

John WH Smith
quelle
Das OP ging auf dieses Problem in einem inzwischen gestrichenen Kommentar ein. Ich fürchte, ich kann keine Antwort für Systeme geben, die gitbasheine Shell-Schnittstelle benötigen , daher meine "leichte". Ich kann eigentlich nicht sagen, wo temporäre Dateien auf einem Windows-System gespeichert sind ...
John WH Smith
1
das auch. Einige verrückt c:\User\Name\..............\stuff. Und es gibt wahrscheinlich 100 von ihnen. Dennoch nähern sich einige Linux - Distributionen dem gleichen Grad des Wahnsinns in /var. Ich war nur neugierig. Es kam mir seltsam vor - meiner Erfahrung nach ist Frust sehr tragbar und Bequemlichkeit weniger. Trotzdem sehr gute Antwort.
mikeserv
1
Vor ungefähr einem Jahr habe ich ein Bash-Skript geschrieben, um Windows Restore Point-Dateien zu bearbeiten, die unter Win2K bis zu WinXP funktionieren (spätere Versionen behandeln diese Dinge anders). Mein Skript verwendet WINDOWS/Tempoder Windows/Tempals Standardverzeichnis für seine temporären Dateien. Dieses Verzeichnis ist auch auf Windows 7-Computern vorhanden. Mit meinem Skript kann der Benutzer jedoch ein alternatives temporäres Verzeichnis in der Befehlszeile angeben.
PM 2Ring
Dies würde unter OS X nicht funktionieren, da Sie eine Vorlage angeben müssen mktemp.
Tyilo
1
Seit El Capitan mktempfunktioniert einfach: simple mktempgibt eine Datei und mktemp -dein Verzeichnis zurück; Keine Vorlagen erforderlich. Das Handbuch wird jedoch nicht aktualisiert.
Franklin Yu
9

Wenn Sie dasselbe in weniger Zeilen suchen ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

Sie könnten dies in einem schreiben.

Frostschutz
quelle
Sie sollten wahrscheinlich auch testen, ob es beschreibbar ist.
Frostschutz
@janos: Wenn alles andere fehlschlägt, bitten Sie den Benutzer, einen Pfad für temporäre Dateien anzugeben, oder erlauben Sie ihm, einen Pfad in der Befehlszeile anzugeben.
PM 2Ring
6

Sie könnten tun:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

Die Shell sollte entweder ein ausführbares Verzeichnis in einer der 4 Alternativen finden oder mit einem aussagekräftigen Fehler beenden. Dennoch definiert POSIX die $TMPDIRVariable (für XCU-Systeme) :

TMPDIR Diese Variable soll einen Pfadnamen eines Verzeichnisses darstellen, das für Programme zur Verfügung gestellt wird, die einen Ort zum Erstellen temporärer Dateien benötigen.

Es erfordert auch den /tmpPfad.

mikeserv
quelle
1
Dies ist die einzig richtige Antwort hier, IMO. Keine Ahnung, was es tut, wenn man sich ohne Stimmen auf den Boden setzt ...
Graeme
2
@Graeme: Vielleicht, weil es völlig unlesbar ist?
SSC
Ich habe hochgestimmt, aber dann zurückgezogen - ja, diese Antwort ist ein Durcheinander. Es scheint auf einem nützlichen Weg zu sein, aber es ist überhaupt nicht klar, was der Code-Snippit versucht - die erste Zeile ist ein Kommentar und die zweite Eins ist ein Fehler (jedenfalls in der Bash). Könnte etwas Arbeit gebrauchen.
Don Hatch
Oh, ich verstehe, die erste Version der Antwort war klarer (immer noch ein Fehler in der zweiten Zeile, wenn Sie tatsächlich versuchen, sie auszuführen) ... und dann hat eine Reihe von Bearbeitungen das Codebeispiel komplett zerstört, sodass es jetzt Unsinn ist. Könnte einen anderen Pass oder zwei verwenden :-)
Don Hatch