Estaciones de trabajo en línea OnWorks Linux y Windows

Logotipo

Alojamiento gratuito en línea para estaciones de trabajo

<Anterior | Contenido | Siguiente>

Trampas

En el Capítulo 10, vimos cómo los programas pueden responder a las señales. También podemos agregar esta capacidad a nuestros scripts. Si bien los scripts que hemos escrito hasta ahora no han necesitado esta capacidad (porque tienen tiempos de ejecución muy cortos y no crean archivos temporales), los scripts más grandes y complicados pueden beneficiarse de tener una rutina de manejo de señales.

Cuando diseñamos una secuencia de comandos grande y complicada, es importante considerar qué sucede si el usuario cierra la sesión o apaga la computadora mientras se ejecuta la secuencia de comandos. Cuando ocurre tal evento, se enviará una señal a todos los procesos afectados. A su vez, los programas que representan esos procesos pueden realizar acciones para asegurar una terminación adecuada y ordenada del programa. Digamos, por ejemplo, que escribimos un script que creaba un archivo temporal durante su ejecución. En el curso de un buen diseño, haríamos que la secuencia de comandos elimine el archivo cuando la secuencia de comandos termine su trabajo. También sería inteligente que la secuencia de comandos elimine el archivo si se recibe una señal que indique que el programa se cerrará antes de tiempo.

golpear proporciona un mecanismo para este propósito conocido como trampa. Las trampas se implementan con el comando incorporado con el nombre apropiado, trampa. trampa utiliza la siguiente sintaxis:

trampa señal de argumento [señal...]

donde argumento es una cadena que se leerá y tratará como un comando y señal es la especificación de una señal que activará la ejecución del comando interpretado.

He aquí un ejemplo sencillo:



#! / Bin / bash


# trap-demo: demostración simple de manejo de señales

#! / Bin / bash


# trap-demo: demostración simple de manejo de señales


trap "echo 'Te estoy ignorando'". SIGINT SIGTERM for i in {1..5}; hacer

echo "Iteración $ i de 5" sueño 5

done

trap "echo 'Te estoy ignorando'". SIGINT SIGTERM for i in {1..5}; hacer

echo "Iteración $ i de 5" sueño 5

done


Este script define una trampa que ejecutará una echo comando cada vez que se recibe la señal SIG-INT o SIGTERM mientras se ejecuta el script. La ejecución del programa se ve así cuando el usuario intenta detener el script presionando Ctrl-c:


[yo @ linuxbox ~] $ trampa-demo

Iteración 1 de 5

Iteración 2 de 5 Te estoy ignorando. Iteración 3 de 5 Te estoy ignorando. Iteración 4 de 5

Iteración 5 de 5

[yo @ linuxbox ~] $ trampa-demo

Iteración 1 de 5

Iteración 2 de 5 Te estoy ignorando. Iteración 3 de 5 Te estoy ignorando. Iteración 4 de 5

Iteración 5 de 5


Como podemos ver, cada vez que el usuario intenta interrumpir el programa, en su lugar se imprime el mensaje.

Construir una cadena para formar una secuencia útil de comandos puede resultar complicado, por lo que es una práctica común especificar una función de shell como comando. En este ejemplo, se especifica una función de shell separada para cada señal que se manejará:



#! / Bin / bash

# trap-demo2: demostración simple de manejo de señales exit_on_signal_SIGINT () {

echo "Script interrumpido". 2> & 1 salida 0

}


salida_on_signal_SIGTERM () {

echo "Script terminado". 2> & 1 salida 0

}


trampa exit_on_signal_SIGINT SIGINT trampa exit_on_signal_SIGTERM SIGTERM

#! / Bin / bash

# trap-demo2: demostración simple de manejo de señales exit_on_signal_SIGINT () {

echo "Script interrumpido". 2> & 1 salida 0

}


salida_on_signal_SIGTERM () {

echo "Script terminado". 2> & 1 salida 0

}


trampa exit_on_signal_SIGINT SIGINT trampa exit_on_signal_SIGTERM SIGTERM



para i en {1..5}; hacer

echo "Iteración $ i de 5" sueño 5

done


para i en {1..5}; hacer

echo "Iteración $ i de 5" sueño 5

done


Este script presenta dos trampa comandos, uno para cada señal. Cada trampa, a su vez, especifica una función de shell que se ejecutará cuando se reciba la señal particular. Tenga en cuenta la inclusión de un salida comando en cada una de las funciones de manejo de señales. Sin un salida, el script continuaría después de completar la función.

Cuando el usuario presiona Ctrl-c durante la ejecución de este script, los resultados se ven así:



[yo @ linuxbox ~] $ trampa-demo2

Iteración 1 de 5

Iteración 2 de 5 Script interrumpido.

[yo @ linuxbox ~] $ trampa-demo2

Iteración 1 de 5

Iteración 2 de 5 Script interrumpido.


imagen

Archivos temporales

Una razón por la que se incluyen controladores de señales en los scripts es para eliminar archivos temporales que el script puede crear para contener resultados intermedios durante la ejecución. Hay algo de arte en nombrar archivos temporales. Tradicionalmente, los programas en sistemas similares a Unix crean sus archivos temporales en el / Tmp directorio, un directorio compartido destinado a dichos archivos. Sin embargo, dado que el directorio se comparte, esto plantea ciertos problemas de seguridad, especialmente para los programas que se ejecutan con privilegios de superusuario. Aparte del paso obvio de establecer los permisos adecuados para los archivos expuestos a todos los usuarios del sistema, es importante dar a los archivos temporales nombres de archivo no predecibles. Esto evita un exploit conocido como ataque de carrera temporal. Una forma de crear un nombre no predecible (pero aún descriptivo) es hacer algo como esto:

tempfile = / tmp / $ (nombre base $ 0). $$. $ RANDOM

Esto creará un nombre de archivo que consiste en el nombre del programa, seguido de su ID de proceso (PID), seguido de un número entero aleatorio. Sin embargo, tenga en cuenta que el $ RAN- DOM La variable de shell solo devuelve un valor en el rango de 1-32767, que no es un rango muy grande en términos informáticos, por lo que una sola instancia de la variable no es suficiente para vencer a un atacante determinado.



imagen

Una mejor forma es utilizar el mktemp programa (no confundir con el mktemp función de biblioteca estándar) para nombrar y crear el archivo temporal. los mk-temp El programa acepta una plantilla como argumento que se utiliza para construir el nombre del archivo. La plantilla debe incluir una serie de caracteres "X", que se reemplazan por un número correspondiente de letras y números aleatorios. Cuanto más larga sea la serie de caracteres "X", más larga será la serie de caracteres aleatorios. Aquí hay un ejemplo:

tempfile = $ (mktemp /tmp/foobar.$$.XXXXXXXXXX)

Esto crea un archivo temporal y asigna su nombre a la variable. archivo temporal. Los caracteres "X" en la plantilla se reemplazan con letras y números aleatorios para que el nombre de archivo final (que, en este ejemplo, también incluye el valor expandido del parámetro especial $$ para obtener el PID) podría ser algo como:

/tmp/foobar.6593.UOZuvM6654

Para los scripts que son ejecutados por usuarios habituales, puede ser conveniente evitar el uso de / Tmp directorio y cree un directorio para archivos temporales dentro del directorio de inicio del usuario, con una línea de código como esta:

[[-d $ HOME / tmp]] || mkdir $ HOME / tmp


Top OS Cloud Computing en OnWorks: