¿Deben guardarse los archivos temporales en / tmp o en el directorio de trabajo actual?

76

Tengo un programa que necesita generar archivos temporales. Está escrito para máquinas de clúster.

Si guardé esos archivos en un directorio temporal de todo el sistema (por ejemplo:) /tmp, algunos usuarios se quejaron de que el programa falló porque no tenían acceso adecuado a / tmp. Pero si guardaba esos archivos en el directorio de trabajo, esos usuarios también se quejaban de que no querían ver esos archivos misteriosos.

¿Cuál es una mejor práctica? ¿Debo insistir en que guardar /tmpes el enfoque correcto y defender cualquier falla como "trabajando según lo previsto" (es decir, solicite a su administrador el permiso / acceso adecuado)?

SmallChess
fuente
3
compruebe si el programa tiene acceso y si no encuentra otro directorio temporal
fanático del trinquete
24
Si su administrador arruinó los derechos de acceso, definitivamente debería arreglarlo. ¿Qué haría si su administrador olvidara agregar derechos de ejecución a su programa?
Doc Brown
77
No encontrará / tmp en la mayoría de los sistemas Windows, pero hay una llamada del sistema operativo que le indicará dónde colocar los archivos temporales.
Ian
28
Si algunas personas no tenían acceso a /tmpun sistema similar a Unix, está mal configurado. El superusuario debería hacer algo así chmod 1777 /tmp.
musiphil
12
Tenga en cuenta que $ TMPDIR podría apuntar a una ruta diferente a la /tmp/que debería usar en su lugar. Ver algunas de las respuestas;)
marcelm

Respuestas:

141

Los archivos temporales deben almacenarse en el directorio temporal del sistema operativo por varias razones:

  • El sistema operativo hace que sea muy fácil crear esos archivos al tiempo que garantiza que sus nombres sean únicos .

  • La mayoría del software de respaldo sabe cuáles son los directorios que contienen archivos temporales y los omite. Si usa el directorio actual, podría tener un efecto importante en el tamaño de las copias de seguridad incrementales si las copias de seguridad se realizan con frecuencia.

  • El directorio temporal puede estar en un disco diferente o en la RAM, lo que hace que el acceso de lectura-escritura sea mucho, mucho más rápido .

  • Los archivos temporales a menudo se eliminan durante el reinicio (si están en un disco RAM, simplemente se pierden). Esto reduce el riesgo de crecimiento infinito si su aplicación no siempre elimina los archivos temporales correctamente (por ejemplo, después de un bloqueo).

    La limpieza de los archivos temporales del directorio de trabajo podría volverse desordenada fácilmente si los archivos se almacenan junto con los archivos de la aplicación y del usuario. Puede mitigar este problema creando un directorio separado dentro del directorio actual, pero esto podría conducir a otro problema:

  • La longitud del camino podría ser demasiado larga en algunas plataformas. Por ejemplo, en Windows, los límites de ruta para algunas API, marcos y aplicaciones son terribles , lo que significa que puede alcanzar fácilmente dicho límite si el directorio actual ya está en la jerarquía del árbol y los nombres de sus archivos temporales son demasiado largos.

  • En los servidores, la supervisión del crecimiento del directorio temporal a menudo se realiza de inmediato. Si usa un directorio diferente, es posible que no se controle, y monitorear todo el disco no ayudará a descubrir fácilmente que son los archivos temporales los que ocupan más y más lugar.

En cuanto a los errores de acceso denegado, asegúrese de dejar que el sistema operativo cree un archivo temporal para usted. El sistema operativo puede, por ejemplo, saber que para un usuario determinado, se debe usar un directorio diferente /tmpo no C:\Windows\tempdebe usarse; por lo tanto, al acceder a esos directorios directamente, es posible que encuentre un error de acceso denegado.

Si obtiene un acceso denegado incluso cuando usa la llamada del sistema operativo, bueno, simplemente significa que la máquina estaba mal configurada; Esto ya fue explicado por Blrfl . Depende del administrador del sistema configurar la máquina; No tiene que cambiar su aplicación.

Crear archivos temporales es sencillo en muchos idiomas. Algunos ejemplos:

  • Golpetazo:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
    
  • Pitón:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
    
  • C#:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
    
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
    
  • Rubí:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close
    

Tenga en cuenta que en algunos casos, como en PHP y Ruby, el archivo se elimina cuando se cierra el identificador. Ese es un beneficio adicional de usar las bibliotecas incluidas con el lenguaje / marco.

Arseni Mourzenko
fuente
2
¿Qué quiere decir con "asegúrese de dejar que el sistema operativo cree un archivo temporal para usted". Entonces, en lugar de, por ejemplo, fopen("/tmp/mytmpfile", "w");¿debería hacer alguna llamada al sistema para manejar archivos temporales?
simon
30
@gurka: Debería llamar tmpfile(3)para generar sus archivos temporales, o al menos llamar mktemp(3)para crear los nombres de los archivos.
TMN
3
@ TMN: son solo funciones de biblioteca que se ejecutan en el espacio del usuario, y no tienen ninguna magia para evitar el error de permiso otorgado por el sistema operativo.
musiphil
25
@musiphil Tanto tmpfile como mktemp utilizan variables externas para determinar la ruta de los archivos temporales. Estos pueden haber sido configurados para apuntar a otro directorio que / tmp /, quizás un directorio por usuario. Intentar crear un nombre de archivo manualmente en / tmp / puede fallar, mientras que tmpfile y mktemp devolverían rutas válidas.
tubería
2
@musiphil: Nunca dije que solucionarían el problema de los permisos, estaba respondiendo a su pregunta sobre el uso de llamadas al sistema para crear los archivos.
TMN
33

¿Debo insistir en que guardar en / tmp es el enfoque correcto y defenderme ante cualquier falla como "funcionando según lo previsto" (es decir, solicite a su administrador el permiso de acceso adecuado)?

Hay estándares para esto, y lo mejor que puedes hacer es cumplir con ellos.

POSIX, que es seguido por casi todos los sistemas operativos no mainframe de cualquier importancia con la que es probable que se encuentre, tiene disposiciones para crear archivos temporales con nombres únicos en un directorio utilizando valores predeterminados que pueden ser reconfigurados por el entorno:

  • El stdio.hencabezado C puede incluir opcionalmente una P_tmpdirmacro que nombra el directorio temporal del sistema.
  • TMPDIRes la variable de entorno canónico para cambiar la ubicación de los archivos temporales. Antes de POSIX, se usaban otras variables, por lo que tiendo a ir con la primera de eso o TMP, TEMPDIRy TEMPeso tiene un valor, puntear y usar el valor predeterminado del sistema si ninguna de ellas existe.
  • Los mkstemp()y tempfile()las funciones generarán archivos temporales únicos.

Si a sus usuarios se les niega la capacidad de crear archivos temporales, el sistema está mal configurado o los administradores no están aclarando cuál es su política sobre tales cosas. En esos casos, se mantendría firme al decir que su programa se ajusta a un estándar de portabilidad bien establecido y que su comportamiento se puede cambiar utilizando las variables de entorno que especifica el estándar.

Blrfl
fuente
P_tmpdirno es parte de stdio.hlo definido por la especificación del lenguaje C. Puede estar definido por POSIX o SVID.
musiphil
1
@musiphil: Como lo implica la respuesta (ahora aclarada), es parte de POSIX. (Técnicamente, es una extensión de sistema X / Open que POSIX incorporó. Ver pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Totalmente de acuerdo con todo lo anterior. Un buen ejemplo son los sistemas Linux con pam_tmpdir: esto establece TMPDIRy TMPdebe ser diferente para cada usuario, por su solidez y privacidad. También es útil poder configurar TMPDIRun solo comando: si tiene su directorio temporal habitual en un sistema de archivos RAM para la velocidad, es posible que deba hacerlo para los comandos que generan enormes archivos temporales (como un gigante sort, por ejemplo). ¡No ignore los estándares / convenciones que sus usuarios esperan!
Toby Speight
Definitivamente verifique el entorno para la ubicación de los archivos temporales y nunca codifique / tmp. Debido a que un tmp compartido tiene problemas de seguridad, una mitigación que he visto a menudo es crear directorios por usuario / tmp sin permiso de lectura y escritura para nadie más. Elimina posibles condiciones de carrera y ataques de enlaces simbólicos.
Zan Lynx
9

El directorio de archivos temporales depende en gran medida del sistema operativo / entorno. Por ejemplo, un directorio web-server-temp está separado del os-temp-dir por razones de seguridad.

En ms-windows cada usuario tiene su propio directorio temporal.

debe usar createTempFile () para esto si dicha función está disponible.

k3b
fuente
1
Solo tenga en cuenta las limitaciones ocultas del sistema operativo en Windows. Descubrimos por las malas que el número máximo de archivos en una carpeta se limitaba a 65.565. Claro, eso es un montón de archivos, y seguro, que nunca deben concebiblemente tener que muchos por ahí. ¿Pero estás seguro de que cada aplicación se limpia después de sí misma de manera oportuna y con buen comportamiento?
Mike Hofer el
Ah, he visto tu comentario demasiado tarde. Acabo de escribir lo mismo arriba. Por cierto, el límite se debe principalmente a la mecánica de la función GetTimeFileName (), no NTFS. Ese límite de carpeta que mencionó se aplica solo a FAT32 .
JensG
9

Las respuestas anteriores, aunque correctas, no son válidas para la mayoría de los clústeres de computadoras a gran escala.

Los clústeres de computadoras no siempre siguen las convenciones estándar para las máquinas, generalmente por buenas razones, y no tiene sentido discutirlo con los administradores de sistemas.

Su directorio actual se refiere al sistema de archivos central, al que se accede a través de la red. Esto no solo es lento, sino que también pone cargas en el sistema para el resto de los usuarios, por lo que no debe usarlo a menos que no esté escribiendo mucho y pueda recuperarse si el trabajo falla.

Los nodos de computación tienen su propio disco duro, que es el sistema de archivos más rápido disponible y lo que debería estar usando. La documentación del clúster debería decirle qué es, por lo general /scratch, /tmp/[jobid]o alguna variable de entorno no estándar ( $SNIC_TMPen una de las que uso).

Entonces, lo que recomiendo es que sea configurable por el usuario. Los valores predeterminados pueden ser los primeros a los que tiene acceso de escritura:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Pero espere una baja tasa de éxito con este enfoque y asegúrese de emitir una gran advertencia.

Editar: agregaré otra razón para forzarlo a ser configurado por el usuario. Uno de mis clústeres se ha $TMPDIRestablecido en /scratch, que puede escribir el usuario y en el disco duro local. Pero, la documentación dice que cualquier cosa que escriba fuera /scratch/[jobid]puede eliminarse en cualquier momento, incluso en el medio de la ejecución. Entonces, si sigue los estándares y confía $TMPDIR, encontrará bloqueos aleatorios, muy difíciles de depurar. Entonces, puedes aceptar $TMPDIR, pero no confiar en él.

Algunos otros clústeres tienen esta variable configurada correctamente, por lo que puede agregar una opción para confiar explícitamente $TMPDIR, de lo contrario, emitirá una advertencia grande y gorda.

Davidmh
fuente
1
¿Cuáles son exactamente las respuestas anteriores?
Tulains Córdova
2
Entonces, lo que está diciendo aquí es que debido a que algunos clústeres que no dan el paso trivial de adherirse a un estándar bien establecido para indicar a los programas dónde escribir sus archivos temporales, se requiere una personalización adicional específica del clúster por programa. Té bastante débil si me preguntas.
Blrfl
@Blrfl puedes mover los estándares todo lo que quieras y escribir código que se adhiera perfectamente a ellos, y siempre se bloquea; puedes intentar luchar con los administradores de sistemas de cada grupo que uses; o puedes aceptar tu fe y hacerla configurable. Además, en HPC generalmente se necesita adaptar el código a los detalles del clúster de todos modos (RAM disponible, velocidad relativa de los sistemas de archivos, implementación de MPI, disponibilidad general de recursos ...), no existe un "tamaño único para todos".
Davidmh
@Davidmh: Entendido, pero no es el punto. El estándar lo hace configurable de una manera no sorprendente. Si llevo el código conforme conocido a un clúster donde no se sigue el estándar, tengo que configurarlo exactamente en un lugar, como en el punto de entrada. Esa es una cosa menos en el resto del código para auditar, modificar y arriesgarse a equivocarse.
Blrfl
1

Para muchas aplicaciones, debería considerar poner archivos temporales en $XDG_RUNTIME_DIRo $XDG_CACHE_HOME(los otros directorios XDG son para archivos no temporales). Para obtener instrucciones sobre cómo calcularlos si no se pasan explícitamente en el entorno, consulte la especificación basada en XDG o busque una biblioteca que ya implemente esa parte.

Sin embargo, $XDG_RUNTIME_DIRtenga en cuenta que se trata de una nueva incorporación y que no existe una reserva estándar para los sistemas más antiguos debido a problemas de seguridad.

Si ninguno de esos es adecuado, entonces /tmpes el lugar correcto. Usted debe nunca se asume el directorio actual se puede escribir.

o11c
fuente
-2

Esto es más como una alternativa, pero puede desvincular () el archivo inmediatamente después de fopen (). Depende del patrón de uso de cource.

Desvincular los archivos, si se puede hacer, ayuda de varias maneras:

  • el archivo no se ve; el usuario no lo ve.
  • el archivo no se ve desde otros procesos; no existe la posibilidad de que otro proceso modifique el archivo por error.
  • limpieza fácil si el programa falla.

Los archivos deben crearse en / tmp. Si el usuario no tiene derechos para crear un archivo allí, esto significa que el sistema está mal configurado.

Los archivos no se pueden crear en el directorio de inicio de los usuarios. Muchos usuarios, como "nadie", "www-data" y muchos otros, no tienen derechos para escribir en sus directorios de inicio, o incluso están chroot () - ed. Tenga en cuenta que incluso en el entorno chroot / tmp todavía existe.

Mella
fuente
Si bien esta podría ser una buena idea en general, no ayuda a los usuarios que carecen de permisos de escritura en el directorio en el que se creará el archivo.
5gon12eder
44
Tampoco responde la pregunta, que es dónde colocar los archivos temporales.
Blrfl
Creo que mi respuesta es de alguna manera importante. Edité, probablemente sea más claro de esta manera.
Nick