Pregunta

Estoy creando archivos temporales de una escritura del golpe. Los estoy borrando al final del tratamiento, pero dado que el script se está ejecutando desde hace mucho tiempo, si lo mato o simplemente CTRL-C durante la carrera, los archivos temporales no se eliminan.
¿Hay alguna manera de atrapar a los eventos y limpiezas de seguridad de los archivos antes de que termine la ejecución?

Además, ¿hay algún tipo de buenas prácticas para la denominación y la ubicación de los archivos temporales?
Yo actualmente no estoy seguro entre el uso de:

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

y

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

O tal vez es que hay algunas soluciones mejores?

¿Fue útil?

Solución

También podemos establecer una "trampa " para ejecutar el salir o en un control-c para limpiar.

trap "{ rm -f $LOCKFILE; }" EXIT

Por otra parte, uno de mis UNIX-ismos favoritos es para abrir un archivo y, a continuación, eliminarlo, mientras que todavía tiene abierto. El archivo permanece en el sistema de archivos y se puede leer y escribir, pero tan pronto como sale de su programa, el archivo se va. No estoy seguro de cómo se haría en bash que, sin embargo.

Por cierto: Un argumento lo daré a favor de mktemp en lugar de utilizar su propia solución: si el usuario anticipa que su programa va a crear archivos temporales grandes, puede ser que desee establecer TMPDIR a un lugar más grande, como / var / tmp . mktemp reconoce que, su solución de enrollado a mano (segunda opción) no lo hace. Suelo utilizar TMPDIR=/var/tmp gvim -d foo bar, por ejemplo.

Otros consejos

Por lo general crear un directorio en el que colocar todos mis archivos temporales, e inmediatamente después, crear un controlador de EXIT para limpiar este directorio cuando el script finaliza.

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

Si coloca todos los archivos temporales de bajo $MYTMPDIR, a continuación, todos ellos serán borrados cuando el script finaliza en la mayoría de las circunstancias. Matando a un proceso con SIGKILL (kill -9) mata el proceso de inmediato, sin embargo, por lo que su manejador de salida no se ejecutará en ese caso.

Usted desea utilizar el comando trampa para manejar la salida de la secuencia de comandos o señales como CTRL-C. Ver el Wiki de Greg para más detalles.

Para sus TEMPFILES, utilizando basename $0 es una buena idea, así como proporcionar una plantilla que proporciona suficiente espacio para archivos temporales:

tempfile() {
    tempprefix=$(basename "$0")
    mktemp /tmp/${tempprefix}.XXXXXX
}

TMP1=$(tempfile)
TMP2=$(tempfile)

trap 'rm -f $TMP1 $TMP2' EXIT

Hemos de tener en cuenta que la elegida respuesta es bashism, lo que significa que la solución

trap "{ rm -f $LOCKFILE }" EXIT

funcionaría sólo en bash (que no cogerá Ctrl + C si la cáscara es dash o sh clásico), pero si quieres compatibilidad entonces usted todavía necesita para enumerar todas las señales que desea trampa.

También hay que tener en cuenta que cuando la escritura sale de la trampa para señal "0" (SALIDA aka) se realiza siempre que provocaría una doble ejecución de comandos trap.

Que la razón para no apilar todas las señales en una sola línea si hay señal de SALIDA.

Para entender mejor que mira siguiente script que trabajará a través de diferentes sistemas sin cambios:

#!/bin/sh

on_exit() {
  echo 'Cleaning up...(remove tmp files, etc)'
}

on_preExit() {
  echo
  echo 'Exiting...' # Runs just before actual exit,
                    # shell will execute EXIT(0) after finishing this function
                    # that we hook also in on_exit function
  exit 2
}


trap on_exit EXIT                           # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR  # 1 2 3 15 30


sleep 3 # some actual code...

exit 

Esta solución le dará un mayor control ya que se puede ejecutar algunos de su código de ocurrencia de señal real justo antes de la salida (función preExit) final y si es necesario se puede ejecutar un código en la señal de salida reales (fase final de salida)

La alternativa de utilizar un nombre de archivo predecible con $$ es un enorme agujero de seguridad y usted debe nunca, nunca, nunca pensar acerca de su uso. Incluso si es sólo un guión personal simple en su PC de usuario único. Es un hábito muy malo que no debería obtener. BugTraq está lleno de "archivo temporal" incidentes de inseguridad. Ver aquí , aquí y aquí para obtener más información sobre el aspecto de seguridad de los archivos temporales.

Estaba pensando inicialmente de citar los tmp1 y Tmp2 asignaciones inseguros, pero en el segundo pensamiento que probablemente no ser una buena idea .

Yo prefiero usar tempfile que crea un archivo en / tmp de la manera segura y que no tiene que preocuparse por su nomenclatura:

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

Usted no tiene que preocuparse por la eliminación de los archivos temporales creados con mktemp. Se eliminarán todos modos más tarde.

Utilice mktemp si es posible, ya que genera archivos más único entonces prefijo '$$'. Y parece que forma más de plataforma cruzada para crear archivos temporales después explícitamente ponerlas en / tmp.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top