J'ai déjà remarqué cela, mais il a été évoqué à nouveau lorsque je répondais "Comment déplacer un répertoire dans un répertoire portant le même nom ?" :
Le mktemp l'utilitaire sous macOS ne se comporte pas de la même façon que l'utilitaire du même nom sous Linux ou BSD (ou du moins OpenBSD) par rapport au TMPDIR variable d'environnement.
Pour créer un fichier temporaire dans le courant répertoire, je peux généralement dire
tmdfile=$(TMPDIR=. mktemp)
ou
tmpfile=$(TMPDIR=$PWD mktemp)
(et de même pour un répertoire temporaire avec mktemp -d ).
Sur macOS, je devrai forcer l'utilitaire à utiliser le répertoire courant en lui donnant un modèle réel, comme dans
tmpfile=(mktemp ./tmp.XXXXXXXX)
car en utilisant le plus pratique tmpfile=$(TMPDIR=. mktemp) ignorerait le TMPDIR variable et créez le fichier sous /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T ou dans un répertoire portant le même nom.
Le manuel de mktemp sur macOS mentionne que
Si le préfixe
-t prefixl'option est donnée,mktempgénérera une chaîne de modèle basée sur le préfixe et
le_CS_DARWIN_USER_TEMP_DIRvariable de configuration si disponible. Emplacements de repli si_CS_DARWIN_USER_TEMP_DIRn'est pas disponible sontTMPDIRet/tmp.
Sur mon système, _CS_DARWIN_USER_TEMP_DIR semble être désactivé :
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
mais par exemple
tmpfile=$(TMPDIR=. mktemp -t hello)
crée toujours un fichier sous /var/folders/.../ (également lors de l'utilisation de $PWD à la place de . ).
Je remarque que
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
mais cela ne m'aide pas beaucoup car je ne saurais pas comment changer cette valeur.
Le macOS mktemp On dit que l'utilitaire vient de FreeBSD, qui à son tour l'a obtenu d'OpenBSD (ce qui devait être il y a un certain temps).
Question :
Est-ce un bogue (ou une omission) dans l'implémentation macOS de mktemp ? Comment changer le DARWIN_USER_TEMP_DIR valeur (ou _CS_DARWIN_USER_TEMP_DIR mentionné par le manuel) à partir d'un script (je voudrais idéalement le désactiver pour que $TMPDIR est prioritaire) ?
Réponse acceptée :
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
Ceci est votre utilisateur local Darwin annuaire. Son nom est simplement un encodage en base 32 modifié de la concaténation de votre MacOS User UUID et votre ID utilisateur MacOS (BSD). Les deux premières lettres de l'encodage sont utilisées comme un système de "seau" pour tenter de maintenir la taille des répertoires à un niveau bas. Ces deux caractères sont les 10 premiers bits encodés de l'UUID de l'utilisateur, car en base 32, un chiffre correspond bien sûr à 5 bits.
Ses sous-répertoires sont votre user local temp et cache local utilisateur répertoires. Leurs noms étaient -Caches- et -Tmp- mais ceux-ci ont été raccourcis en C et T . Il devrait être évident que tous ces noms sont fixes et non modifiables, à moins que vous ne souhaitiez modifier votre ID utilisateur ou UUID utilisateur.
Lorsqu'une application appelle confstr(_CS_DARWIN_USER_TEMP_DIR,…) , la bibliothèque C essaie d'abord de s'assurer que vous avez un utilisateur local répertoire, puis essaie de s'assurer que vous avez un temp local utilisateur répertoire qu'il contient.
S'assurer que vous disposez d'un utilisateur local répertoire n'est pas trivial, car vous n'avez pas accès en écriture à /var/folders . Il existe donc un dirhelper Démon de lancement Mach qui s'exécute avec des privilèges de superutilisateur et qui crée ces répertoires en toute sécurité, répondant aux appels Mach IPC des applications depuis l'implémentation de confstr() dans leurs bibliothèques C. Vous faites avoir un accès en écriture à l'utilisateur local répertoire (une fois créé) et donc les bibliothèques C juste mkdir() ses enfants directement s'ils n'existent pas déjà.
Si cela réussit, le mktemp le programme ne regarde jamais la valeur du TMPDIR variable d'environnement, car le repli dans mktemp le code provient de l'appel de confstr() pour appeler getenv() pas l'inverse. confstr(_CS_DARWIN_USER_TEMP_DIR,…) réussira presque toujours. Ses modes de défaillance sont des choses comme le dirhelper launch dæmon ne pouvant pas être exécuté, ou la tentative de création du T sous-répertoire échouant avec une erreur autre que que le répertoire existe déjà.
Vous pouvez mettre autre chose qu'un répertoire comme T , mais cela sera régulièrement nettoyé par le dirhelper launch dæmon, qui est aussi ce qui supprime des éléments dans /var/folders . Désactiver le dirhelper launch dæmon causera ses propres problèmes, dont le moindre ne sera pas /var/folders ne pas être nettoyé. Vous refuser l'autorisation d'écrire sur votre utilisateur local répertoire interférera potentiellement avec tous les autres en utilise, il est utilisé pour plus qu'un simple T sous-répertoire.
Votre meilleure option (à part fournir un modèle) est de faire T un lien symbolique, mais c'est encore loin d'être bon car cela affectera bien sûr toutes vos applications en cours d'exécution qui pourraient, au même instant, vouloir créer un fichier temporaire.
Ni DARWIN_USER_TEMP_DIR ni _CS_DARWIN_USER_TEMP_DIR sont des noms de variables. Ce sont des noms, pour le getconf utilitaire et pour confstr() fonction de bibliothèque, d'une chaîne de configuration.