Respuestas:
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"
Puede asegurarse de que se elimine un archivo cuando salga la secuencia de comandos (incluidas las muertes y bloqueos) abriendo un descriptor de archivo en el archivo y eliminándolo. El archivo se mantiene disponible (para el script; en realidad no para otros procesos, pero /proc/$PID/fd/$FD
es una solución alternativa) siempre que el descriptor de archivo esté abierto. Cuando se cierra (lo que el núcleo hace automáticamente cuando sale el proceso) el sistema de archivos elimina el archivo.
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
exec 3>"$tmpfile"
rm "$tmpfile"
: ...
echo foo >&3
/proc
- excepto para sistemas que no lo tienen.
exec 3> "$tmpfile"
hacer? ¿No es eso útil solo si tmpfile es un script independiente?
cat <&3
dará Bad file descriptor
. Le agradecería si lo arregla o lo elimina; la desinformación no ayuda mucho.
Use mktemp
para crear un archivo o directorio temporal:
temp_file=$(mktemp)
O para un direcotry:
temp_dir=$(mktemp -d)
Al final del script, debe eliminar el archivo / directorio temporal:
rm ${temp_file}
rm -R ${temp_dir}
mktemp crea un archivo en el /tmp
directorio o en el directorio dado con el --tmpdir
argumento.
trap "rm -f $temp_file" 0 2 3 15
inmediatamente después de crear el archivo para que cuando el script salga o se detenga con ctrl-C
el archivo, aún se elimine.
EXIT
es el único gancho para trap
?
kill -9 $somepid
. Esa señal particular de muerte es muerte instantánea sin que nada más suceda.
bash -c 'echo $$; trap "echo foo" 0; sleep 5'
EXIT
es suficiente.
Si está en un sistema que tiene mktemp , debe usarlo como otras respuestas.
Con POSIX toolchest:
umask 0177
tmpfile=/tmp/"$0"."$$"."$(awk 'BEGIN {srand();printf "%d\n", rand() * 10^10}')"
trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
: > "$tmpfile"
EXIT
es el único gancho para trap
?
tmpfile
aún se debe eliminar antes de la salida del script, pero no cuando el script recibió otras señales.
That's not what happens
?
mktemp
se originó en HP / UX con una sintaxis diferente. Todd C. Miller creó uno diferente para OpenBSD a mediados de los 90 (copiado por FreeBSD y NetBSD) y más tarde también lo hizo disponible como una utilidad independiente (www.mktemp.org). Ese es el que generalmente se usaba en Linux hasta que mktemp
se agregó una utilidad (en su mayoría compatible) a los coreutils de GNU en 2007. Solo para decir que uno realmente no puede decir mktemp
es una utilidad de GNU.
Algunos proyectiles tienen la característica incorporada.
zsh
La =(...)
forma de sustitución del proceso utiliza un archivo temporal. Por ejemplo, se =(echo test)
expande a la ruta de un archivo temporal que contiene test\n
.
$ {cat $file; ls -l /dev/fd/3; echo test2 >&3; cat $file} 3<> ${file::==(echo test)}
test
lrwx------ 1 stephane stephane 64 Jan 30 11:19 /dev/fd/3 -> /tmp/zshMLbER0
test2
Ese archivo se elimina automáticamente, una vez que el comando ha finalizado.
Here-files o here-strings in bash
y zsh
se implementan como archivos temporales eliminados.
Entonces si lo haces:
exec 3<<< test
El descriptor de archivo 3 está conectado a un archivo temporal eliminado que contiene test\n
.
Puede obtener su contenido con:
cat <&3
Si está en Linux, también puede leer o escribir en ese archivo a través de /dev/fd/3
$ exec 3<<< test
$ cat <&3
test
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo
(algunos otros depósitos usan tuberías, o pueden usarse /dev/null
si el documento here está vacío).
No hay mktemp
utilidad POSIX. POSIX, sin embargo, especifica una mkstemp(template)
API de C , y la m4
utilidad estándar expone esa API con la mkstemp()
función m4 con el mismo nombre.
mkstemp()
le da un nombre de archivo con una parte aleatoria que se garantizó que no existía en el momento en que se llamó a la función. Sí crea el archivo con permisos 0600 de forma libre de carrera.
Entonces, podrías hacer:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
Sin embargo, tenga en cuenta que debe manejar la limpieza al salir, aunque si solo necesita escribir y leer el archivo un número fijo de veces, puede abrirlo y eliminarlo justo después de crearlo para here-doc / here- enfoque de cuerda arriba:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
# open once for writing, twice for reading:
exec 3> "$tempfile" 4< "$tempfile" 5< "$tempfile"
rm -f -- "$tmpfile"
cmd >&3 # store something in the temp file
exec 3>&- # fd no longer needed
# read the content twice:
cat <&4
cat <&5
Puede abrir el archivo para leerlo una vez y rebobinar entre dos lecturas, sin embargo, no hay una utilidad POSIX que pueda rebobinar ( lseek()
), por lo que no puede hacerlo de forma portátil en un script POSIX ( zsh
( sysseek
incorporado) y ksh93
( <#((...))
operador) puede hazlo sin embargo).
<()
=(...)
.
Aquí hay una respuesta un poco mejorada en la línea de Hauke Laging:
#!/bin/bash
tmpfile=$(mktemp) # Create a temporal file in the default temporal folder of the system
# Lets do some magic for the tmpfile to be removed when this script ends, even if it crashes
exec {FD_W}>"$tmpfile" # Create file descriptor for writing, using first number available
exec {FD_R}<"$tmpfile" # Create file descriptor for reading, using first number available
rm "$tmpfile" # Delete the file, but file descriptors keep available for this script
# Now it is possible to work with the temporal file
echo foo >&$FD_W
echo bar >&$FD_W # Note that file descriptor always concatenates, not overwrites
cat <&$FD_R
Mi flujo de trabajo normalmente con archivos temporales se debe a algún script bash que estoy probando. Quiero tee
hacerlo para poder ver que está funcionando y guardar la salida para la próxima iteración de mi proceso. He creado un archivo llamadotmp
#!/bin/bash
echo $(mktemp /tmp/$(date +"%Y-%m-%d_%T_XXXXXX"))
para que pueda usarlo como
$ some_command --with --lots --of --stuff | tee $(tmp)
La razón por la que me gusta la fecha y hora formateada antes de los valores aleatorios es que me permite encontrar el archivo tmp que acabo de crear fácilmente, y no tengo que pensar en cómo nombrarlo la próxima vez (y centrarme en obtener mi script dang) trabajar).