Ich habe das schon einmal bemerkt, aber es wurde erneut aufgeworfen, als ich antwortete „Wie verschiebe ich ein Verzeichnis in ein Verzeichnis mit demselben Namen?“:
Das mktemp
Utility unter macOS verhält sich bezüglich TMPDIR
nicht so wie das gleichnamige Utility unter Linux oder BSD (oder zumindest OpenBSD). Umgebungsvariable.
Zum Erstellen einer temporären Datei im aktuellen Verzeichnis, kann ich normalerweise sagen
tmdfile=$(TMPDIR=. mktemp)
oder
tmpfile=$(TMPDIR=$PWD mktemp)
(und ähnlich für ein temporäres Verzeichnis mit mktemp -d
).
Unter macOS muss ich das Dienstprogramm zwingen, das aktuelle Verzeichnis zu verwenden, indem ich ihm eine tatsächliche Vorlage gebe, wie in
tmpfile=(mktemp ./tmp.XXXXXXXX)
weil das bequemere tmpfile=$(TMPDIR=. mktemp)
verwendet wird würde das TMPDIR
ignorieren Variable und erstellen Sie die Datei unter /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
oder in einem ähnlich benannten Verzeichnis.
Das Handbuch für mktemp
unter macOS erwähnt dies
Wenn das Präfix -t prefix
Option angegeben ist, mktemp
generiert eine Vorlagenzeichenfolge basierend auf dem Präfix und
dem _CS_DARWIN_USER_TEMP_DIR
Konfigurationsvariable, falls vorhanden. Fallback-Standorte, wenn_CS_DARWIN_USER_TEMP_DIR
nicht verfügbar sind TMPDIR
und /tmp
.
Auf meinem System _CS_DARWIN_USER_TEMP_DIR
scheint nicht gesetzt zu sein:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
aber z.B.
tmpfile=$(TMPDIR=. mktemp -t hello)
erstellt immer noch eine Datei unter /var/folders/.../
(auch bei Verwendung von $PWD
anstelle von .
).
Das merke ich
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
aber das hilft mir nicht viel, da ich nicht wüsste, wie ich diesen Wert ändern soll.
Das macOS mktemp
Utility soll von FreeBSD stammen, das wiederum von OpenBSD stammt (was schon eine ganze Weile her sein muss).
Frage:
Ist dies ein Fehler (oder eine Auslassung) in der macOS-Implementierung von mktemp
? Wie ändere ich das DARWIN_USER_TEMP_DIR
Wert (oder _CS_DARWIN_USER_TEMP_DIR
im Handbuch erwähnt) aus einem Skript heraus (idealerweise würde ich es so deaktivieren wollen, dass $TMPDIR
hat Vorrang)?
Akzeptierte Antwort:
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
Dies ist Ihr lokaler Darwin-Benutzer Verzeichnis. Sein Name ist einfach eine modifizierte Basis-32-Kodierung der Verkettung Ihrer MacOS-Benutzer-UUID und Ihre MacOS (BSD) Benutzer-ID. Die ersten beiden Buchstaben der Codierung werden als „Bucket“-System verwendet, um zu versuchen, die Verzeichnisgröße gering zu halten. Diese beiden Zeichen sind die codierten ersten 10 Bits der Benutzer-UUID, denn in Basis 32 ist eine Ziffer natürlich 5 Bits.
Seine Unterverzeichnisse sind Ihre lokale Benutzer-Temp und lokaler Benutzercache Verzeichnisse. Früher hießen sie -Caches-
und -Tmp-
aber diese wurden auf C
gekürzt und T
. Es sollte offensichtlich sein, dass alle diese Namen fest und unveränderbar sind, es sei denn, Sie sind bereit, Ihre Benutzer-ID oder Benutzer-UUID zu ändern.
Wenn eine Anwendung confstr(_CS_DARWIN_USER_TEMP_DIR,…)
aufruft , versucht die C-Bibliothek zuerst sicherzustellen, dass Sie einen lokalen Benutzer haben Verzeichnis und versucht dann sicherzustellen, dass Sie eine lokale temporäre Benutzerdatei haben Verzeichnis darin.
Stellen Sie sicher, dass Sie einen lokalen Benutzer haben Verzeichnis ist nicht trivial, da Sie keinen Schreibzugriff auf /var/folders
haben . Es gibt also einen dirhelper
Mach startet Dæmon, der mit Superuser-Privilegien läuft und diese Verzeichnisse sicher erstellt, indem er auf Mach-IPC-Aufrufe von Anwendungen innerhalb der Implementierung von confstr()
antwortet in ihren C-Bibliotheken. Sie tun Schreibzugriff auf den Benutzer local haben Verzeichnis (einmal erstellt) und damit die C-Bibliotheken einfach mkdir()
seine Kinder direkt, falls sie noch nicht existieren.
Gelingt dies, wird die Datei mktemp
Programm schaut nie auf den Wert von TMPDIR
Umgebungsvariable, da der Fallback in mktemp
Der Code stammt vom Aufruf von confstr()
zum Aufrufen von getenv()
nicht umgekehrt. confstr(_CS_DARWIN_USER_TEMP_DIR,…)
wird fast immer gelingen. Seine Fehlermodi sind Dinge wie dirhelper
launch dæmon nicht ausgeführt werden kann, oder der Versuch, das T
zu erstellen Unterverzeichnis schlägt mit einem Fehler anders als fehl dass das Verzeichnis bereits existiert.
Sie könnten etwas anderes als ein Verzeichnis als T
angeben , aber dies wird regelmäßig vom dirhelper
bereinigt Starten Sie dæmon, das auch Dinge in /var/folders
löscht . dirhelper
deaktivieren launch dæmon wird eigene Probleme verursachen, nicht zuletzt /var/folders
nicht gereinigt werden. Verweigern Sie sich selbst die Schreibberechtigung für Ihren lokalen Benutzer Verzeichnis wird potenziell alle anderen stören Verwendungen davon, da es für mehr als nur ein T
verwendet wird Unterverzeichnis.
Ihre beste Option (abgesehen von der Bereitstellung einer Vorlage) ist, T
zu erstellen ein symbolischer Link, aber das ist noch lange nicht gut, da es natürlich alle laufenden Anwendungen von Ihnen betrifft, die möglicherweise im selben Moment eine temporäre Datei erstellen möchten.
Weder DARWIN_USER_TEMP_DIR
noch _CS_DARWIN_USER_TEMP_DIR
sind Variablennamen. Es sind Namen für getconf
Dienstprogramm und für confstr()
Bibliotheksfunktion, einer Konfigurationszeichenfolge.