¿Se deben guardar los archivos temporales en / tmp o en el directorio de trabajo actual?

74

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 el acceso adecuado a / tmp. Pero si guardé esos archivos en el directorio de trabajo, los usuarios también se quejaron de que no querían ver esos archivos misteriosos.

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

    
pregunta SmallChess 05.04.2016 - 13:40

6 respuestas

137

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

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

  • La mayoría del software de copia de seguridad 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 memoria RAM, lo que hace que el acceso de lectura-escritura sea 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).

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

  • La longitud de ruta 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 golpear fácilmente tales Límite si el directorio actual ya está en lo más profundo de 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 monitoree, y la supervisión de todo el disco no ayudará a descubrir fácilmente que son los archivos temporales los que ocupan cada vez más lugar.

En cuanto a los errores de acceso denegado, asegúrese de permitir 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 que no sea /tmp o C:\Windows\temp ; por lo tanto, al acceder directamente a esos directorios, es posible que encuentre un error de acceso denegado.

Si obtiene un acceso denegado incluso al usar la llamada del sistema operativo, bueno, simplemente significa que la máquina estaba mal configurada; Esto fue ya explicado por Blrfl . Es responsabilidad del administrador del sistema configurar la máquina; no tienes que cambiar tu aplicación.

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

  • Bash:

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

    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);
    
  • Ruby:

    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 manejador. Eso es un beneficio adicional de usar las bibliotecas incluidas con el lenguaje / marco.

    
respondido por el Arseni Mourzenko 05.04.2016 - 13:46
33
  

¿Debo insistir en que guardar en / tmp es el enfoque correcto y defenderse de cualquier falla como "trabajando como se esperaba" (es decir, pregunte a su administrador para obtener el permiso 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 que no son mainframe de cualquier significado que pueda encontrar, tiene disposiciones para crear archivos temporales con un nombre único en un directorio utilizando valores predeterminados que pueden ser reconfigurados por el entorno :

  • El encabezado C stdio.h puede incluir opcionalmente una macro P_tmpdir que nombra el directorio temporal del sistema.
  • TMPDIR es la variable de entorno canónica para cambiar la ubicación de los archivos temporales. Antes de POSIX, se usaban otras variables, por lo que tiendo a ir con el primero de eso o TMP , TEMPDIR y TEMP que tiene un valor, marcando y usando el valor predeterminado del sistema si no existe ninguna.
  • Las funciones mkstemp() y tempfile() generarán archivos temporales únicos.

Si a los usuarios se les está negando la capacidad de crear archivos temporales, el sistema está mal configurado o los administradores no están dejando claro cuál es su política al respecto. En esos casos, sería muy firme al decir que su programa cumple con un estándar de portabilidad bien establecido y que su comportamiento se puede cambiar utilizando las variables de entorno que el estándar especifica.

    
respondido por el Blrfl 05.04.2016 - 15:02
9

El directorio de archivos temporales es altamente dependiente del sistema operativo / entorno. Por ejemplo, un servidor web-temp-directorio está separado de os-temp-dir por razones de seguridad.

Bajo ms-windows cada usuario tiene su propio temp-dir.

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

    
respondido por el k3b 05.04.2016 - 14:10
9

Las respuestas anteriores, aunque correctas, no son válidas para la mayoría de los clusters 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 discutirlas 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 informáticos 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 debe indicar qué es, típicamente /scratch , /tmp/[jobid] , o alguna variable de entorno no estándar ( $SNIC_TMP en 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 un bajo índice de éxito con este enfoque y asegúrese de emitir una gran advertencia.

Editar: Agregaré otra razón para forzar que sea configurada por el usuario. Uno de mis clústeres tiene $TMPDIR establecido en /scratch , que el usuario puede escribir en el disco duro local. Pero, la documentación dice que cualquier cosa que escriba fuera de /scratch/[jobid] puede eliminarse en cualquier momento, incluso en medio de la ejecución. Por lo tanto, si sigue los estándares y confía en $TMPDIR , encontrará bloqueos aleatorios, muy difíciles de depurar. Por lo tanto, puede 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 en $TMPDIR , de lo contrario, emitir una gran advertencia.

    
respondido por el Davidmh 06.04.2016 - 09:48
1

Para muchas aplicaciones, debería considerar colocar archivos temporales en $XDG_RUNTIME_DIR o $XDG_CACHE_HOME (los otros directorios XDG son para archivos no temporales). Para obtener instrucciones sobre cómo calcularlos si no se transfieren explícitamente en el entorno, consulte la especificación XDG en su especificación o encuentra una biblioteca que ya implementa esa parte.

Sin embargo, tenga en cuenta que $XDG_RUNTIME_DIR es una nueva adición y no hay un respaldo estándar para sistemas más antiguos debido a problemas de seguridad.

Si ninguno de estos es adecuado, entonces /tmp es el lugar correcto. Debería nunca asumir que el directorio actual es de escritura.

    
respondido por el o11c 07.04.2016 - 01:49
-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 en otros procesos, no hay posibilidad de que otro proceso modifique el archivo por error.
  • limpieza fácil si falla el programa.

Los archivos se deben crear en / tmp. Si el usuario no tiene derechos para crear el 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 "nobody", "www-data" y muchos otros, no tienen derechos para escribir en sus directorios principales, o incluso son chroot () - ed. Tenga en cuenta que incluso en chroot environment / tmp todavía existe.

    
respondido por el Nick 06.04.2016 - 19:37

Lea otras preguntas en las etiquetas