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 prefix
l'option est donnée,mktemp
générera une chaîne de modèle basée sur le préfixe et
le_CS_DARWIN_USER_TEMP_DIR
variable de configuration si disponible. Emplacements de repli si_CS_DARWIN_USER_TEMP_DIR
n'est pas disponible sontTMPDIR
et/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.