L'ho notato prima, ma è stato richiamato di nuovo mentre rispondevo "Come spostare la directory in una directory con lo stesso nome?":
Il mktemp
l'utilità su macOS non si comporta allo stesso modo dell'utilità con lo stesso nome su Linux o BSD (o almeno OpenBSD) rispetto a TMPDIR
variabile di ambiente.
Per creare un file temporaneo nel corrente directory, di solito posso dire
tmdfile=$(TMPDIR=. mktemp)
o
tmpfile=$(TMPDIR=$PWD mktemp)
(e allo stesso modo per una directory temporanea con mktemp -d
).
Su macOS, dovrò forzare l'utilità a utilizzare la directory corrente assegnandole un modello vero e proprio, come in
tmpfile=(mktemp ./tmp.XXXXXXXX)
perché usando il più conveniente tmpfile=$(TMPDIR=. mktemp)
ignorerebbe il TMPDIR
variabile e creare il file in /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
o in una directory con nome simile.
Il manuale per mktemp
su macOS lo menziona
Se il -t prefix
viene fornita l'opzione mktemp
genererà una stringa modello basata sul prefisso e
sul _CS_DARWIN_USER_TEMP_DIR
variabile di configurazione se disponibile. Posizioni di riserva se_CS_DARWIN_USER_TEMP_DIR
non è disponibile sono TMPDIR
e /tmp
.
Sul mio sistema, _CS_DARWIN_USER_TEMP_DIR
sembra non essere impostato:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
ma ad es.
tmpfile=$(TMPDIR=. mktemp -t hello)
crea comunque un file in /var/folders/.../
(anche quando si utilizza $PWD
al posto di .
).
Lo sto notando
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
ma questo non mi aiuta molto in quanto non saprei come modificare questo valore.
Il mktemp
di macOS si dice che l'utilità provenga da FreeBSD, che a sua volta l'ha ottenuta da OpenBSD (che deve essere stato parecchio tempo fa).
Domanda:
È un bug (o un'omissione) nell'implementazione macOS di mktemp
? Come posso modificare il DARWIN_USER_TEMP_DIR
valore (o _CS_DARWIN_USER_TEMP_DIR
menzionato dal manuale) dall'interno di uno script (idealmente vorrei deselezionarlo in modo che $TMPDIR
ha la precedenza)?
Risposta accettata:
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
Questo è il tuo utente locale Darwin directory. Il suo nome è semplicemente una codifica in base 32 modificata della concatenazione del tuo UUID utente di MacOS e il tuo ID utente MacOS (BSD). Le prime due lettere della codifica vengono utilizzate come un sistema "bucket" per tentare di mantenere basse le dimensioni delle directory. Questi due caratteri sono i primi 10 bit codificati dell'UUID utente, perché in base 32 una cifra è ovviamente 5 bit.
Le sue sottodirectory sono la tua temp locale utente e cache locale utente directory. I loro nomi erano -Caches-
e -Tmp-
ma quelli sono stati abbreviati in C
e T
. Dovrebbe essere evidente che tutti questi nomi sono fissi e non modificabili, a meno che tu non sia disposto a modificare il tuo ID utente o UUID utente.
Quando un'applicazione chiama confstr(_CS_DARWIN_USER_TEMP_DIR,…)
, la libreria C cerca innanzitutto di assicurarsi di avere un utente locale directory, quindi cerca di assicurarti di avere una temp locale utente directory al suo interno.
Assicurati di avere un utente locale directory non è banale, perché non hai accesso in scrittura a /var/folders
. Quindi c'è un dirhelper
Dæmon di lancio di Mach che viene eseguito con privilegi di superutente e che crea in modo sicuro queste directory, rispondendo alle chiamate IPC di Mach dalle applicazioni dall'interno dell'implementazione di confstr()
nelle loro librerie C. Tu fai avere accesso in scrittura a utente locale directory (una volta creata) e quindi le librerie C solo mkdir()
direttamente i suoi figli se non esistono già.
Se ciò riesce, il mktemp
il programma non guarda mai il valore di TMPDIR
variabile di ambiente, perché il fallback in mktemp
Il codice di 's proviene dalla chiamata di confstr()
per chiamare getenv()
Non il contrario. confstr(_CS_DARWIN_USER_TEMP_DIR,…)
quasi sempre ci riuscirà. Le sue modalità di errore sono cose come il dirhelper
launch dæmon che non può essere eseguito, o il tentativo di creare il T
sottodirectory non riuscita con un errore diverso da che la directory esiste già.
Potresti mettere qualcosa di diverso da una directory come T
, ma questo verrà regolarmente ripulito dal dirhelper
launch dæmon, che è anche ciò che elimina le cose in /var/folders
. Disabilitazione del dirhelper
launch dæmon causerà problemi propri, non ultimo dei quali sarà /var/folders
non essere pulito. Negare a te stesso l'autorizzazione in scrittura sul tuo utente locale directory interferirà potenzialmente con tutti gli altri lo usa, essendo usato per qualcosa di più di un semplice T
sottodirectory.
La tua migliore opzione (oltre a fornire un modello) è creare T
un collegamento simbolico, ma questo è ancora tutt'altro che valido perché ovviamente influenzerà tutte le tue applicazioni in esecuzione che potrebbero, nello stesso istante, voler creare un file temporaneo.
Né DARWIN_USER_TEMP_DIR
né _CS_DARWIN_USER_TEMP_DIR
sono nomi di variabili. Sono nomi, per getconf
utility e per confstr()
funzione di libreria, di una stringa di configurazione.