Capitulo 16 - Bash Scripting avanzado PDF

Title Capitulo 16 - Bash Scripting avanzado
Author Matias Segovia
Course Sistemas Operativos I
Institution Universidad Nacional Arturo Jauretche
Pages 16
File Size 1.1 MB
File Type PDF
Total Downloads 72
Total Views 154

Summary

Bash Scripting avanzado - sistemas operativos...


Description

CAPÍTULO 16 BASH SCRIPTING AVANZADO

Introducción y objetivos de aprendizaje En la lección anterior comenzamos con una introducción al shell bash scripting. Pero hay mucho más que se puede hacer con ellos. Vamos a discutir estos temas avanzados: manipular strings, evaluar expresiones booleanas, y el favorito de todos, depurar los scripts que acabamos de escribir. Por lo tanto, comencemos!

Objetivos de aprendizaje Al final de este capítulo, debes ser capaz de: 

Manipular strings para realizar acciones tales como comparación y clasificación.



Usar expresiones Booleanas cuando trabajamos con varios tipos de datos, incluidos strings, números y archivos.



Uso de la instrucción case para controlar opciones de la línea de comandos.



Usar bucles para ejecutar una o más líneas de código repetidamente.



Depurar scripts usando set -x y set +x.



Crear directorios y archivos temporales.



Crear y utilizar números aleatorios.

Sección 1: Operaciones con strings Manejo de strings Vamos a profundizar y averiguar cómo trabajar con strings en scripts. Una variable string contiene una secuencia de caracteres de texto. Puede incluir letras, números, símbolos y signos de puntuación. Algunos ejemplos: abcde, 123, abcde 123, abcde-123, &acbde=%123 Los Operadores de string incluyen aquellos que hacen la comparación, orden y búsqueda de longitud. En la tabla siguiente se muestra el uso de algunos operadores de string básicos. Operador

Significado

[[ string1 > string2 ]]

Compara el orden de clasificación de string1 y string2

[[ string1 == string2 ]]

Compara los caracteres de string1 con los caracteres

de string2 MyLen1=${#string1}

Guarda la longitud de string1 en la variable myLen1.

Ejemplo de operaciones con strings (strings)

Veamos la captura de pantalla anterior. En el primer ejemplo, se compara el primer string con el segundo string y se muestra un mensaje apropiado utilizando la instrucción if. En el segundo ejemplo, se pasa un nombre de archivo y se busca si ese archivo existe en el directorio actual o no.

Partes de un string A veces, podemos no necesitar en una comparación que se utilice un string completa. Para extraer el primer carácter de un string podemos especificar: ${string:0:1} Aquí 0 es el desplazamiento en el string (es decir, desde que carácter va a comenzar) donde debe comenzar la extracción y 1 es el número de caracteres que se van a extraer. Para extraer todos los caracteres de una string después del punto (.), utilicemos la siguiente expresión: ${string#*.}

Pruebas con strings

Operaciones con strings

Sección 2: Expresiones booleanas Expresiones booleanas Las expresiones booleanas se evalúan como TRUE (VERDADERO) o FALSE (FALSO), y los resultados se obtienen mediante diferentes operadores booleanos indicados en la tabla:

Operador

Operación

Significado

&&

AND

La acción se llevará a cabo sólo si ambas condiciones se evalúan como true.

||

OR

La acción se llevará a cabo si alguna de las condiciones se evalúa como true.

!

NOT

La acción se llevará a cabo si la condición se evalúa como false.

Notemos que si hay varias condiciones enlazadas con el operador && el procesamiento se detiene tan pronto como una condición se evalúa como false. Por ejemplo, si tenemos A && B && C y A es verdadera, pero B es falsa, C no se ejecutará nunca. Igualmente, si se utilizamos el operador ||, el proceso se detiene tan pronto como algo es cierto. Por ejemplo, si tiene A || B || C y A es falsa y B es true, tampoco C se ejecutará nunca.

Pruebas con expresiones booleanas Las expresiones booleanas retornan los valores TRUE ó FALSE. Podemos utilizar estas expresiones cuando trabajamos con varios tipos de datos, incluyendo strings, números así como con archivos. Por ejemplo, para comprobar si existe un archivo, utilicemos la siguiente prueba condicional:

[ -e ] Del mismo modo, para comprobar si el valor de number1 es mayor que el valor de number2, utilicemos la siguiente prueba condicional: [ $number1 -gt $number2 ] El operador -gt devuelve TRUE si number1 es mayor que number2.

Ejemplo de uso de operadores

Sección 3: la instrucción Case.

La instrucción case La instrucción case se utiliza en los casos en que el valor de una variable puede conducir a diferentes rutas de ejecución. Las instrucciones case se utilizan a menudo para manejar las opciones de línea de comandos. A continuación se presentan algunas de las ventajas de utilizar la instrucción case: 

Es más fácil de leer y escribir.



Es una buena alternativa para anidar, bloques de código if-then-else-if multi-nivel.



Le permite comparar una variable con varios valores a la vez.



Reduce la complejidad de un programa.

Estructura de la instrucción case. Aquí vemos la estructura básica de la instrucción case: case expression in pattern1) execute commands;; pattern2) execute commands;; pattern3) execute commands;; pattern4) execute commands;; * ) execute some default commands or nothing;; esac

Ejemplo de la instrucción case. Tenemos aquí un ejemplo de una instrucción case:

Sección 4: Bucles

Construcciones de bucle Mediante las instrucciones de bucle, podemos ejecutar una o más líneas de código repetidamente. Normalmente debe hacerlo hasta que una prueba condicional devuelva true o false como se requiere. En la mayoría de lenguajes de programación se utilizan a menudo tres tipos de bucles: 

for



while



until

Todos estos loops son fácilmente utilizados para repetir un conjunto de sentencias hasta que la condición de salida sea verdadera (true).

El bucle 'for' El bucle for funciona sobre cada elemento de una lista de elementos. La sintaxis del bucle for es: for variable-name in list do Execute one iteration for each ítem in the List until the list is finished done En este caso, variable-name y lista se sustituyen según corresponda (ver ejemplos). Como con otras construcciones de bucle, las declaraciones que se repiten deben estar encerradas por do y done.

Las capturas de pantalla muestran un ejemplo del bucle for para imprimir la suma de los números 1 a 4.

Utilización de las instrucciones for y case

El bucle while El bucle while repite un conjunto de sentencias mientras comando de control devuelve true. La sintaxis es: while condition is true do Commands for execution ---done El conjunto de comandos que van a ser repetidos deben estar encerrados entre do y done. Podemos utilizar cualquier comando u operador como condición. A menudo se encierra entre corchetes ([ ]). Aquí las capturas de pantalla muestran un ejemplo del bucle while que calcula el factorial de un número.

Instrucción While

El bucle until El bucle until repite un conjunto de sentencias mientras el comando de control es false. Por lo tanto es esencialmente el opuesto del bucle while. La sintaxis es: Until condition is false do Commands for execution ---done De forma similar al bucle while, el conjunto de comandos que va a ser repetido debe estar encerrado entre do y done. Se puede utilizar cualquier comando u operador como condición. La captura de pantalla siguiente muestra un ejemplo del bucle until que muestra los números impares entre 1 y 10.

El bucle until

Sección 5: Depuración de scripts Introducción a la depuración de scripts Mientras trabajamos con scripts y comandos, podemos cometer errores. Estas pueden deberse a un error en la secuencia de comandos, tal como una sintaxis incorrecta, u otros inconvenientes como un archivo que falta o permisos insuficientes para realizar una operación. Estos errores pueden reportarse con un código de error específico, pero a menudo sólo producen resultados incorrectos o confusos. Entonces, ¿cómo podemos abordar la identificación y la corrección de un error? La depuración (Debugging) nos ayuda a detectar y solucionar estos errores, y es una de las tareas más importantes que realiza un administrador del sistema.

Más información sobre Script Debugging Antes de corregir un error (o bug), es imprescindible conocer su origen. En bash shell scripting, podemos ejecutar un script en modo debug haciendo bash x ./script_file. El modo de depuración nos ayuda a identificar el error porque: 

Agrega el carácter + como prefijo en cada comando.



Muestra cada comando antes de ejecutarlo.



Podemos depurar sólo partes seleccionadas de un script (si lo deseamos) con: set -x ... set +x

# activa la depuración # apaga la depuración

Las siguientes capturas de pantalla demuestran un archivo script llamado c15s9 (imagen izquierda) y el resultado de la ejecución en modo de depuración (imagen derecha).

Redireccionando errores a un archivo y/o pantalla En UNIX/Linux, todos los programas que se ejecutan comienzan con tres archivos abiertos con secuencias que se inician como se indica en la tabla: Secuencia de archivo

Descripción

Descriptor de archivo

stdin

Entrada estándar, por defecto es el teclado/terminal para los programas que se ejecutan desde la línea de comandos.

0

stdout

Salida estándar, de forma predeterminada es la pantalla para los programas que se ejecutan desde la línea de comandos.

1

stderr

Error estándar, donde se muestran los mensajes de error de salida o son guardados

2

Utilizando redirección podemos guardar los flujos de salida stdout y stderr en un archivo o dos archivos separados para su posterior análisis, después de ejecutar un programa o comando. En la pantalla de la izquierda tenemos un buggy shell script (script con errores). En la pantalla de la derecha se ejecuta el script con errores y los errores se redirigen al archivo "error.txt". Utilizando "cat" podemos visualizar el contenido de "error.txt" que muestra los errores de la ejecución del buggy Shell script (presumiblemente para una mayor depuración).

Sección 6: algunas técnicas útiles adicionales Creación de directorios y archivos temporales Consideremos una situación en la que queremos recuperar 100 registros desde un archivo con 10.000 registros. Necesitaremos un lugar para almacenar la información extraída, quizás en un archivo temporal, mientras realiza el procesamiento ulterior en él. Los archivos temporales (y directorios) están diseñados para almacenar datos durante un corto periodo de tiempo. Generalmente se organiza de tal manera que estos archivos desaparecen cuando finaliza el programa con ellos. Aunque también se puede usar touch para crear un archivo temporal, esto puede hacer que sea fácil para los hackers obtener acceso a los datos. La mejor práctica es crear nombres aleatorios e impredecibles para el almacenamiento temporal. Una forma de hacerlo es con la utilidad mktemp como en los siguientes ejemplos: Con la utilidad mktemp los XXXXXXXX se sustituyen con caracteres aleatorios para garantizar que el nombre del archivo temporal no se pueda predecir fácilmente y sólo es conocido dentro de su programa. Comando

Uso

TEMP=$(mktemp /tmp/tempfile.XXXXXXXX)

Crea un archivo temporal

TEMPDIR=$(mktemp -d /tmp/tempdir.XXXXXXXX)

Crea un directorio temporal

Ejemplo de creación de un archivo y un directorio temporal Primero, cuidado!: si alguien crea un enlace simbólico desde un archivo temporal conocido utilizado por root en el archivo /etc/passwd , como este: $ ln -s /etc/passwd /tmp/tempfile Podría haber un problema si el script ejecutado por root tiene una línea como esta: echo $VAR > /tmp/tempfile El archivo de contraseñas se sobrescribirá con el contenido del archivo temporal.

Para evitar tal situación, asegúrese de aleatorizar los nombres de archivo temporales mediante la sustitución de la línea de arriba con las siguientes líneas: TEMP=$(mktemp /tmp/tempfile.XXXXXXXX) echo $VAR > $TEMP

Descartar la salida con /dev/null Algunos comandos como find se producen gran cantidad de salida, la cual puede abrumar a la consola. Para evitar esto, podemos redirigir la salida a un gran archivo especial (device node) un dispositivo llamado /dev/null. Este archivo es llamado también bit bucket o black hole. Este descarta todos los datos que fueron escritos y nunca devuelve un error en las operaciones de escritura. Utilizando los operadores de redirección apropiados, podemos hacer desaparecer la salida de comandos que normalmente generan salida stdout o stderr: $ find / > /dev/null En el comando anterior, todo el flujo de salida estándar es ignorado, pero los errores seguirán apareciendo en la consola.

Números aleatorios y datos A menudo es útil generar números aleatorios y otros datos aleatorios al realizar tareas tales como: 1. Realización de tareas relacionadas con la seguridad. 2. Reinicialización de los dispositivos de almacenamiento. 3. Borrado y/o ocultamiento de los datos existentes. 4. Generación de datos sin sentido para ser utilizado en pruebas.

Esos números aleatorios podemos generarlos mediante la variable de entorno $RANDOM, que deriva del generador de números aleatorios del kernel de Linux, o mediante la función de biblioteca OpenSSL, que utiliza el algoritmo FIPS140 para generar números aleatorios para el cifrado. Para leer más acerca de FIPS140, véase http://en.wikipedia.org/wiki/FIPS_140-2 El ejemplo muestra cómo utilizar fácilmente la variable de entorno method para generar números aleatorios.

Cómo genera números aleatorios el Kernel Algunos servidores tienen generadores de números aleatorios por hardware que toman como entrada distintos tipos de señales de ruido, tales como ruido térmico y el efecto fotoeléctrico. Un transducer convierte este ruido en una señal eléctrica, la cual es nuevamente convertida en un número digital mediante un convertidor A-D. Este número se considera aleatorio. Sin embargo, la mayoría de las computadoras no contiene tal hardware especializado y en su lugar confía en los eventos creados durante el arranque para crear los datos brutos necesarios. Independientemente de cuál de estas dos fuentes se usa, el sistema mantiene un conjunto de estos números digitales/bits aleatorios llamado entropy pool. Los números aleatorios son creados a partir de este conjunto de entropía. El kernel de Linux ofrece los nodos de dispositivo /dev/random y /dev/urandom que constituyen el conjunto de entropía para proporcionar números aleatorios que se extraen de la estimación del número de bits de ruido en el conjunto de entropía. /dev/random se usa cuando se necesita aleatoriedad de muy alta calidad, tales como one-time pad o la generación de una clave, pero es relativamente lento para proporcionar vaulores. /dev/urandom es más rápida y adecuada (suficiente) para la mayoría de usos criptográficos. Además, cuando el conjunto de entropía está vacío, /dev/random está bloqueado y no genera ningún número hasta que el ruido ambiental adicional (tráfico de red, el movimiento del ratón, etc.) se recopila mientras que /dev/urandom reutiliza el pool interno para producir más bits pseudoaleatorios.

Sumario Has completado este capítulo. Resumamos los conceptos clave cubiertos: 

Se puedens manipular strings para realizar acciones tales como comparación, ordenar y buscar la longitud.



Se pueden utilizar expresiones booleanas cuando se trabaja con distintos tipos de datos, incluidos strings, números, así como archivos.



El resultado de una expresión Booleana es verdadera o falsa.



Los operadores utilizados en las expresiones Booleanas incluyen los operadores && (AND) || (OR), y ! (NOT).



Analizamos las ventajas de utilizar la instrucción case en escenarios donde el valor de una variable puede conducir a diferentes rutas de ejecución.



Los métodos de depuración de secuencias de comandos ayudan a detectar y solucionar errores.



Las salidas estándar y de error provenientes de un comando del shell se puede redirigir fácilmente en el mismo archivo o en archivos separados para ayudar en la depuración y guardar los resultados



Linux permite crear directorios y archivos temporales, que almacenan datos de corta duración, ambos ahorran espacio y aumentan la seguridad.



Linux ofrece varias maneras diferentes de generar números aleatorios, que son ampliamente utilizados....


Similar Free PDFs