linux - una - Creando archivos temporales en bash
variables de entorno linux bash (4)
¿Hay formas objetivamente mejores de crear archivos temporales en scripts bash?
Normalmente solo les nombro lo que me viene a la mente, como tempfile-123, ya que se eliminará cuando el script termine. ¿Hay alguna desventaja al hacer esto aparte de sobreescribir un posible archivo temporal (tempfile-123) en la carpeta actual? ¿O hay alguna ventaja en crear un archivo temporal de una manera más cuidadosa?
¿Hay alguna ventaja en crear un archivo temporal de una manera más cuidadosa?
Los archivos temporales generalmente se crean en el directorio temporal (como /tmp
) donde todos los demás usuarios y procesos tienen acceso de lectura y escritura (cualquier otro script puede crear los nuevos archivos allí). Por lo tanto, la secuencia de comandos debe tener cuidado al crear los archivos, como usar con los permisos correctos (por ejemplo, solo para el propietario, ver: help umask
) y el nombre del archivo no debe adivinarse fácilmente (idealmente al azar). De lo contrario, si los nombres de archivo no son únicos, puede crear conflictos con el mismo script ejecutado varias veces (por ejemplo, condición de raza ) o algún atacante podría secuestrar información sensible (por ejemplo, cuando los permisos son demasiado abiertos y el nombre de archivo es fácil de adivinar) o crear / reemplazando el archivo con su propia versión del código (como reemplazar los comandos o las consultas SQL según lo que se está almacenando).
Puede usar el siguiente enfoque para crear el directorio temporal:
TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"
o archivo temporal:
TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"
Sin embargo, todavía es predecible y no se considera seguro.
Según el man mktemp
, podemos leer:
Tradicionalmente, muchos scripts de shell toman el nombre del programa con el pid como sufijo y lo utilizan como un nombre de archivo temporal. Este tipo de esquema de nombres es predecible y la condición de carrera que crea es fácil de ganar para un atacante.
Por lo tanto, para estar seguro, se recomienda utilizar el comando mktemp
para crear un archivo o directorio temporal único ( -d
).
Es posible que desee ver mktemp
La utilidad mktemp toma la plantilla de nombre de archivo dada y sobrescribe una parte de la misma para crear un nombre de archivo único. La plantilla puede ser cualquier nombre de archivo con un cierto número de ''X'' añadidas, por ejemplo /tmp/tfile.XXXXXXXXXX. Los ''X'' finales se reemplazan por una combinación del número de proceso actual y letras aleatorias.
Para más detalles: man mktemp
La página man de mktemp(1)
explica bastante bien:
Tradicionalmente, muchos scripts de shell toman el nombre del programa con el pid como sufijo y lo utilizan como un nombre de archivo temporal. Este tipo de esquema de nombres es predecible y la condición de carrera que crea es fácil de ganar para un atacante. Un enfoque más seguro, aunque aún inferior, es crear un directorio temporal utilizando el mismo esquema de nombres. Si bien esto permite garantizar que un archivo temporal no será subvertido, aún permite un ataque de denegación de servicio simple. Por estas razones, se sugiere usar mktemp en su lugar.
En un script, invoco mktemp algo así como
mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
que crea un directorio temporal en el que puedo trabajar, y en el que puedo nombrar con seguridad los archivos reales, algo que se puede leer y utilizar.
mktemp
no es estándar, pero sí existe en muchas plataformas. Las "X" generalmente se convertirán en aleatoriedad, y más probablemente serán más aleatorias; sin embargo, algunos sistemas (busybox ash, para uno) limitan esta aleatoriedad de manera más significativa que otros
Por cierto, la creación segura de archivos temporales es importante para algo más que simples scripts de shell. Es por eso que python tiene tempfile , perl tiene File::Temp , ruby tiene Tempfile , etc ...
Sí, use mktemp .
Creará un archivo temporal dentro de una carpeta que está diseñada para almacenar archivos temporales y le garantizará un nombre único. Muestra el nombre de ese archivo:
> mktemp
/tmp/tmp.xx4mM3ePQY
>