GNU/Linux >> Linux Esercitazione >  >> Linux

Mktemp su Macos non onora $tmpdir?

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.

Correlati:Linux:come inoltrare il traffico tra gli spazi dei nomi di rete Linux?

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.

DARWIN_USER_TEMP_DIR_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.


Linux
  1. Docker non aggiorna le modifiche nella directory

  2. Come posso ottenere che la schermata GNU non si avvii nella mia home directory in OS X?

  3. Il demone di trasmissione non rileva la directory di controllo

  4. perché sftp rmdir non funziona?

  5. SCP - non una directory - Cosa sto facendo di sbagliato?

Perché è Rm -rf e non Rmdir -rf?

Come eseguire il comando "trova" solo sulla directory corrente e non sulle sottodirectory

SVN controlla il contenuto di una cartella, non la cartella stessa

Rimuovi solo i file nella directory su Linux NOT directory

Perché il mio collegamento simbolico crea un file e non una cartella?

pip install pickle non funziona - nessun file o directory di questo tipo