GNU/Linux >> Tutoriales Linux >  >> Linux

¿Mktemp en Macos no respeta $ tmpdir?

Me di cuenta de esto antes, pero volvió a aparecer cuando respondía "¿Cómo mover un directorio a un directorio con el mismo nombre?":

El mktemp La utilidad en macOS no se comporta igual que la utilidad del mismo nombre en Linux o BSD (o al menos OpenBSD) con respecto al TMPDIR variable de entorno.

Para crear un archivo temporal en el actual directorio, normalmente puedo decir

tmdfile=$(TMPDIR=. mktemp)

o

tmpfile=$(TMPDIR=$PWD mktemp)

(y de manera similar para un directorio temporal con mktemp -d ).

En macOS, tendré que obligar a la utilidad a usar el directorio actual dándole una plantilla real, como en

tmpfile=(mktemp ./tmp.XXXXXXXX)

porque usar el tmpfile=$(TMPDIR=. mktemp) más conveniente ignoraría el TMPDIR variable y cree el archivo en /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T o en un directorio con un nombre similar.

El manual para mktemp en macOS menciona que

Si el -t prefix se da la opción, mktemp generará una cadena de plantilla basada en el prefijo y
el _CS_DARWIN_USER_TEMP_DIR variable de configuración si está disponible. Ubicaciones alternativas si
_CS_DARWIN_USER_TEMP_DIR no está disponible son TMPDIR y /tmp .

En mi sistema, _CS_DARWIN_USER_TEMP_DIR parece estar desarmado:

$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'

pero por ejemplo

tmpfile=$(TMPDIR=. mktemp -t hello)

todavía crea un archivo en /var/folders/.../ (también cuando se usa $PWD en lugar de . ).

Me estoy dando cuenta de que

$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/

pero esto no me ayuda mucho ya que no sabría cómo cambiar este valor.

macOS mktemp Se dice que la utilidad proviene de FreeBSD, que a su vez la obtuvo de OpenBSD (que debe haber sido hace bastante tiempo).

Pregunta:

¿Es esto un error (u omisión) en la implementación de macOS de mktemp? ? ¿Cómo cambio el DARWIN_USER_TEMP_DIR? valor (o _CS_DARWIN_USER_TEMP_DIR mencionado en el manual) desde dentro de una secuencia de comandos (lo ideal sería desactivarlo para que $TMPDIR tiene prioridad)?

Respuesta aceptada:

/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/

Este es su usuario local de Darwin directorio. Su nombre es simplemente una codificación base 32 modificada de la concatenación de su UUID de usuario de MacOS y su ID de usuario de MacOS (BSD). Las dos primeras letras de la codificación se utilizan como un sistema de "cubos" para intentar mantener bajos los tamaños de los directorios. Esos dos caracteres son los primeros 10 bits codificados del UUID de usuario, porque en base 32 un dígito tiene, por supuesto, 5 bits.

Sus subdirectorios son su usuario temporal local y caché local del usuario directorios. Sus nombres solían ser -Caches- y -Tmp- pero se han acortado a C y T . Debería ser evidente que todos estos nombres son fijos e inmutables, a menos que esté dispuesto a cambiar su ID de usuario o UUID de usuario.

Cuando una aplicación llama a confstr(_CS_DARWIN_USER_TEMP_DIR,…) , la biblioteca C primero intenta asegurarse de que tiene un usuario local directorio, luego intenta asegurarse de que tiene un temporario local de usuario directorio dentro de él.

Relacionado:Linux:¿cómo reenviar el tráfico entre espacios de nombres de red de Linux?

Asegurarse de tener un usuario local directorio no es trivial, porque no tiene acceso de escritura a /var/folders . Entonces hay un dirhelper Demonio de lanzamiento de Mach que se ejecuta con privilegios de superusuario y que crea estos directorios de forma segura, respondiendo a las llamadas de Mach IPC desde aplicaciones desde dentro de la implementación de confstr() en sus bibliotecas C. Tu haces tener acceso de escritura al usuario local directorio (una vez creado) y las bibliotecas C solo mkdir() sus hijos directamente si aún no existen.

Si esto tiene éxito, el mktemp el programa nunca mira el valor de TMPDIR variable de entorno, porque la reserva en mktemp El código es de llamar a confstr() para llamar a getenv() no de la otra manera. confstr(_CS_DARWIN_USER_TEMP_DIR,…) casi siempre tendrá éxito. Sus modos de falla son cosas como el dirhelper el demonio de lanzamiento no se puede ejecutar, o el intento de crear el T el subdirectorio falla con un error distinto de que el directorio ya existe.

Podría poner algo que no sea un directorio como T , pero esto será limpiado regularmente por el dirhelper lanzar daemon, que también es lo que elimina cosas en /var/folders . Deshabilitar el dirhelper launch daemon causará sus propios problemas, uno de los cuales será /var/folders no limpiarse. Negarse a sí mismo permiso de escritura en su usuario local directorio potencialmente interferirá con todos los otros usos de él, siendo usado para algo más que un T subdirectorio.

Su mejor opción (aparte de proporcionar una plantilla) es hacer T un enlace simbólico, pero esto todavía está lejos de ser bueno porque, por supuesto, afectará a todas sus aplicaciones en ejecución que podrían, en el mismo instante, querer crear un archivo temporal.

Ni DARWIN_USER_TEMP_DIR ni _CS_DARWIN_USER_TEMP_DIR son nombres de variables. Son nombres, para el getconf utilidad y para el confstr() función de biblioteca, de una cadena de configuración.


Linux
  1. ¿Por qué es Rm -rf y no Rmdir -rf?

  2. Cómo ejecutar el comando "buscar" solo en el directorio actual y no en los subdirectorios

  3. SVN verifica el contenido de una carpeta, no la carpeta en sí

  4. Docker no actualiza los cambios en el directorio

  5. ¿Cómo hago para que la pantalla GNU no se inicie en mi directorio de inicio en OS X?

¿Eliminar todos los archivos en un directorio cuyo nombre no coincide con una línea en una lista de archivos?

¿Vsftpd no muestra el contenido de un directorio?

¿El comando `ls` no muestra los últimos contenidos del directorio?

¿Núcleo volcado, pero el archivo principal no está en el directorio actual?

¿Por qué mi enlace simbólico crea un archivo y no una carpeta?

pip install pickle no funciona - no existe tal archivo o directorio