Conceptos Fundamentales sobre UNIX Laboratorio 15.2.8 – Escritura de Scripts de Shell (Tiempo estimado: 60 min.) Objetivos: • • Escribir y ejecutar un script de shell simple Escribir, ejecutar y hacer debug de un script de shell más avanzado Trasfondo: En este laboratorio, el alumno escribirá, ejecutará y hará debug de scripts de shell simples y más complejos. Los scripts de shell básicos son pequeños archivos que consisten en varios comandos UNIX que muestran información básica del sistema o manipulan archivos. Scripts de shell más complejos consisten en variables y comandos de programación incorporados que incluyen al comando read para una entrada interactiva, los comandos condicionales if, test y case y los comandos de bucle for, while y until. No es un requisito que el usuario escriba scripts de shell para utilizar o administrar un sistema UNIX. No obstante, cuanto más se utiliza UNIX, más encontrará el usuario instancias en las cuales una tarea llevada a cabo reiteradamente no tiene un único comando UNIX. Escribir un script de shell es una forma de crear un comando personalizado que puede llevar a cabo una única tarea o una serie de tareas y puede utilizarse reiteradamente. Herramientas / Preparación: a) Antes de iniciar este laboratorio, el alumno deberá repasar el Capítulo 15 – Introducción a los Scripts de Shell. b) El alumno necesitará lo siguiente: 1. Una ID de login de usuario, por ejemplo user2 y contraseña asignadas por el instructor. 2. Una computadora que funcione con el sistema operativo UNIX. 3. Computadoras en red en el aula con el sistema de archivos de la clase instalado. Notas: _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ 1–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. Utilice el diagrama del árbol de directorios del sistema de Archivos de la Clase para que lo asista en este laboratorio. Estructura del Árbol de Archivos de la Clase Paso 1. Hacer login al CDE. Haga login con el nombre de usuario y la contraseña que le fueron asignados por su instructor en el recuadro de entradas del CDE. Paso 2. Acceder a la Línea de Comandos. Haga clic con el botón derecho en el fondo del espacio de trabajo y haga clic en Tools (Herramientas). Seleccione Terminal desde el menú para abrir una ventana de terminal. Paso 3. Scripts de shell simples. Un alias se utiliza normalmente para ejecutar uno o más comandos simples separados por punto y coma (;). Un script de shell es un archivo de texto que contiene una secuencia de comandos para que el shell ejecute una línea a la vez. Tareas complejas que involucran variables y otras funciones de programación se logran utilizando scripts de shell. Los siguientes son los pasos generales para crear un script de shell: • • • • • • • • • Decidir qué hará el script Hacer una lista de comandos Crear un nuevo archivo para el script Identificar el shell que utilizará el script Agregar comandos y comentarios Guardar el archivo script Hacer ejecutable el archivo script Tipear el nombre del script para ejecutarlo Hacer debug y modificar el script si tienen lugar errores a. Al nombrar un archivo script el alumno deberá evitar utilizar el nombre de un _____________________________ o un _____________________________. b. Normalmente, los archivos script terminan con _______________________________. c. Normalmente, ¿en qué directorio se ubican los scripts de shell creados por el usuario? ___________________________________ 2–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. d. ¿Qué carácter se utiliza antes de un comentario en un archivo script? ____________________ e. ¿Qué se agrega al script que le dice al sistema qué shell utilizar al interpretar las líneas del script? _______________________________ ¿Dónde se ubica esta línea en el archivo script? ___________________________ f. ¿Cuál es el resultado de echo “date”? ______________________________ g. ¿Cuál es el resultado de echo `date`? ______________________________ h. ¿Cuál es el resultado de echo ‘$LOGNAME’? ____________________________ i. ¿Cuál es el resultado de echo “$LOGNAME”? ____________________________ Paso 4. Ejecutar el script. Los scripts de shell siempre se ejecutan en un shell separado. Si un script de shell se ejecuta desde el shell de una ventana de terminal, se inicia un subshell para ejecutarlo. Siempre hay dos formas de ejecutar un script de shell. Un usuario puede utilizar el comando ksh o bash seguido del nombre del archivo script. Un usuario también puede hacer del archivo de script de shell un archivo ejecutable tipeando el nombre del script para ejecutarlo. a. ¿Qué tipearía el alumno para ejecutar el script llamado whoison.sh? El archivo whoison.sh no tiene permiso de ejecución. _______________________________ b. El archivo whoison.sh tiene los permisos r w -r - - r- -. Tipee el comando para otorgar los permisos r w x r - x r - - al archivo. _______________________________ c. El archivo script ejecutable whoison.sh se encuentra en el directorio ~/bin. Cuando el alumno tipea el archivo whoison.sh para ejecutarlo, el shell muestra el mensaje “command not found” (“no se encontró el comando”). ¿Cuál es el problema? ___________________________________ Paso 5. Hacer debug del script. Un problema común al escribir scripts de shell es que el shell no interpreta el comando como lo espera el usuario. Un usuario puede utilizar el comando ksh o bash con las opciones –x (echo) y –v (verbose) para ayudar a identificar en qué parte del script se encuentran los problemas. La opción –x muestra cada línea después de haber sido interpretada por el shell y coloca un signo más (+) después de haber ejecutado cada línea. La opción –v es similar a la opción –x excepto en que muestra los comandos antes de efectuar la sustitución de variables y comandos. a. ¿Qué línea de comandos se introdujo para generar el siguiente resultado desde el archivo script whoison.sh? ___________________________ echo “Hello $LOGNAME!” + echo Hello user10! Hello user10! echo “The number of users logged on is: `who | wc –l`” who | wc –l + echo The number of users logged on is: 3 The number of users logged on is: 3 echo “Today’s date is: `date`” date + echo Today’s date is: Fri Jun 21 2002 Today’s date is: Fri Jun 21 2002 3–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. Paso 6. Crear, ejecutar y hacer debug de un script de shell simple. a. Cree un script llamado firstscript.sh en el directorio home del usuario que haga lo siguiente: 1. Especificar qué shell utiliza el script para interpretar los comandos de script. 2. Describir el propósito del script, que es mostrar los usuarios e imprimir la fecha y el calendario actual. 3. Mostrar en la pantalla “The number of users logged on is:” (“La cantidad de usuarios loggeados es:”) seguido del resultado correcto. 4. Mostrar en la pantalla “Today’s date is:” (“La fecha de hoy es:”) seguido del resultado correcto. 5. Mostrar en la pantalla “Below is the current months calendar” (“A continuación se muestra el calendario del mes en curso”) seguido del resultado correcto. b. Cree un directorio bin en el directorio home del alumno, preparándose para el próximo archivo script del alumno. c. Modifique la variable PATH en .profile o .bash_profile para que el directorio bin que acaba de crearse en el directorio home del alumno se encuentre en la ruta de búsqueda. d. Cree otro script llamado info.sh en el directorio ~/bin. El script deberá contener comentarios y hacer lo siguiente cuando se lo ejecute: 1. Declarar que el script ha de ejecutarse en los shells Korn o Bash. 2. Despejar la pantalla. 3. Saludar a la persona que se loggeó. 4. Mostrar el nombre de host (uname –n). 5. Mostrar la fecha actual. 6. Mostrar el calendario del mes en curso. 7. Mostrar el directorio de trabajo actual. 8. Mostrar el contenido del directorio actual. 9. Mostrar una lista de los procesos que se ejecutan en el shell actual. 10. Imprimir en grandes letras “Have a Nice Day” (“Que tenga un buen día”). e. Ejecute el script info.sh iniciando primero un shell Korn. Luego, hágalo ejecutable para el propietario del archivo y para cualquiera que se encuentre en el mismo grupo. f. Ejecute el script utilizando ksh –x, ksh –v y ksh –xv para hacer debug del mismo. Paso 7. Scripts complejos utilizando programación del shell. Incorporado a cada shell UNIX hay un lenguaje de programación completo que consiste en comandos y construcciones que pueden utilizarse para crear scripts más complejos más allá de simplemente hacer una lista de una serie de comandos. Además de contener comandos de programación del shell tales como if, else, read, case, while y exit, los scripts complejos utilizan variables predefinidas y definidas por el usuario. Variables Una variable es un placeholder o marcador de posición para la información requerida por los procesos para que puedan funcionar de manera apropiada. Una variable tiene un nombre y retiene un valor. Cambiar el valor de una variable se denomina configurar la variable. Existen dos tipos de variables utilizadas en los scripts de shell, las variables del shell y las variables del entorno. Las variables del shell son mantenidas por el shell y sólo son conocidas por el shell actual. Estas variables son variables locales y pueden visualizarse por medio del comando set. Las variables del entorno son variables conocidas por el shell actual y todos los shells hijos o subshells. Las variables del entorno pueden mostrarse por medio del comando env. 4–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. Las variables locales se configuran utilizando el formato VARIABLE=valor. Por ejemplo, BACKUPDIR=/home/user2/myfiles configura la variable llamada BACKUPDIR (backup directory – directorio de respaldo), que es igual al valor de /home/user2/myfiles. Los nombres de las variables van en mayúsculas por convención pero pueden ir en minúsculas. Utilice el comando echo para mostrar el valor de una variable. Parámetros posicionales Los parámetros posicionales son variables del shell especiales incorporadas que pueden proporcionar el nombre del archivo script o argumentos al script a medida que se ejecuta. Sus valores se toman de argumentos de la línea de comandos. Parámetro $0 $1 - $9 $* $# Propósito y ejemplo Comando o nombre del script echo “The name of the script file is $0” Número de argumento de la línea de comandos echo “The first argument is: $1” Todos los argumentos introducidos en la línea de comandos echo “The args specified on the command line = $*” Cantidad de argumentos introducidos en la línea de comandos echo “The number of args on the command line = $#” Entradas interactivas Para hacer más flexible y amigable con el usuario a un script de shell, el alumno puede hacer que el script haga una pausa y pida una única línea de entrada. Esto se logra por medio del comando echo para pedir entradas al alumno y del comando read para hacer una pausa y recibir entradas del teclado. Lo que sea que introduzca el alumno se almacena en el nombre de la variable especificada después del comando read. Las entradas interactivas son una funcionalidad muy potente de los scripts de shell. echo “Enter your name: \c” #Prompt the user for name read name #Read from keyboard and save input in the “name” variable (echo “Introduzca su nombre: \c” #Pedir el nombre del usuario read name #Leer desde el teclado y guardar la entrada en la variable “name”) a. Cree un script llamado whoison.sh en el directorio ~/bin que aceptará un nombre de usuario como argumento, y luego muestra todas las líneas del resultado del comando who que contiene información acerca del usuario especificado. Específicamente, el script hará lo siguiente: 1. Especificar qué shell utiliza el script para interpretar los comandos del script. 2. Leer el primer argumento especificado cuando se ejecuta el script y asignarlo a la variable llamada “user”. 3. Mostrar todas las líneas del resultado del comando who que contiene información acerca del usuario especificado. b. Cree y luego ejecute el script grepfor.sh que se muestra a continuación. Utilice ‘root’ para el patrón y ‘/etc/passwd’ como archivo a buscar la primera vez que el alumno ejecuta el script. #!/bin/ksh # grepfor.sh prompts for a pattern and a file then generates output echo ‘Enter the pattern to search for: \c’ or echo -e ‘Enter the pattern to search for: \c’ (bash) read pattern echo ‘Enter the filename to search: \c’ or echo -e ‘Enter the filename to search: \c’ (bash) 5–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. c. read filename echo echo Results: grep $pattern $filename Modifique el script para que cuando el alumno lo ejecute y especifique “user” para el patrón y “/etc/passwd” para el archivo el resultado sea la cantidad de cuentas del usuario del archivo password que tengan “user” en el nombre. ¿Qué ha cambiado? ______________________________ Paso 8. Scripts complejos que utilizan los comandos if, test y case. Para ser útil, un programa debe poder probar condiciones y tomar decisiones. El programa debe poder examinar el resultado de un comando y elegir entre dos o más cursos de acción. La prueba más simple es determinar si una condición es verdadera o falsa. Si la condición es verdadera, ejecute cualquier cantidad de comandos subsecuentes. Si la condición no es verdadera, continúe con el script. Los comandos que llevan a cabo algunas tareas basándose en si una condición tiene éxito o falla se denominan comandos condicionales. Los tres comandos condicionales más frecuentemente utilizados son if, test y case. El Formato del Comando if-then: if (si) el comando tiene éxito then (entonces) ejecutar comando o comandos fi El Formato del Comando if-then-else: if el comando tiene éxito then ejecutar comando o comandos else ejecutar comando o comandos fi El Formato del Comando if-then-elif (else if): if el comando tiene éxito then ejecutar comando o comandos elif el comando tiene éxito then ejecutar comando o comandos else (de lo contrario) ejecutar comando o comandos fi El comando condicional incorporado al shell test se utiliza a menudo para probar una o más condiciones a continuación del comando if. El Formato del Comando if-test: if test expresión o if [ expresión ] then ejecutar comando o comandos fi El comando del shell incorporado case se utiliza cuando hay muchas condiciones que probar. Formato del comando: case value in value1) Comando Comando ;; *) Comando ;; esac El valor de una variable de caso se compara con valor1, valor2, etc., hasta que coincida. 6–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. a. Modifique el script whoison2.sh del directorio ~/bin para que acepte un nombre de usuario como argumento y si el usuario está loggeado, muestre “<specified user> is currently logged on” (“<el usuario especificado> está loggeado actualmente”). b. Cree un script test1.sh en ~/bin que contenga las siguientes líneas: #!/bin/ksh # test1.sh script to demonstrate the test command echo “Do you want a long listing of the files in the current directory?” echo “ enter y for Yes or n for No:\c” c. Modifique el script test1.sh para que: • Lea la respuesta dada por el usuario que ejecuta el script en una variable llamada ‘answer’. • Pruebe la respuesta introducida por el usuario que ejecuta el script. Si la respuesta es “y”, despeje la pantalla y ejecute un listado largo. De otro modo, si la respuesta es “n”, ejecute ls sin ninguna opción. ¿Qué líneas que restan se agregaron al archivo script para satisfacer los requisitos a y b? Paso 9. Scripts complejos que utilizan control de flujo (bucles). El alumno puede utilizar bucles para controlar el flujo de ejecución de un script. Un bucle repite una secuencia de instrucciones reiteradamente hasta satisfacer una condición predeterminada. A menudo un script tiene que ver con llevar a cabo la misma operación o conjunto de operaciones en cada archivo de un directorio o lista, cada línea de un archivo, o cada palabra de una línea. El shell proporciona tres construcciones de bucles para lograr este tipo de acción: el bucle for, el bucle while, y el bucle until. El bucle for El bucle for ejecuta una lista de comandos una vez por cada valor de una variable de bucle. Formato del Comando: for variable in list do Comandos done El bucle while El bucle while ejecuta reiteradamente un grupo de comandos dentro del cuerpo del bucle hasta que la condición de prueba en la expresión se vuelve falsa. En otras palabras, mientras la expresión es verdadera, ejecute estos comandos. Formato del Comando: while comando do Comandos done El bucle until El bucle until es muy similar al bucle while pero ejecuta una serie de comandos mientras un comando continúa fallando, estado de salida no igual a cero. Cuando el comando finalmente se ejecuta exitosamente, el bucle se termina y la ejecución pasa al primer enunciado que sigue a la construcción done. La condición until se verifica en la parte superior del bucle, no en la inferior. Formato del Comando: until comando do Comandos done 7–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc. a. ¿Qué hace el siguiente script de bucle for cuando se lo ejecuta? #!/bin/bash for FILE in file* do ls -l $FILE done echo “all done!” b. Cree y luego ejecute el script de shell que figura arriba y nómbrelo loop1.sh. Colóquelo en ~/bin. c. Modifique el script loop1.sh para que muestre un listado largo de todos los archivos introducidos en la línea de comandos. Por ejemplo $ loop1.sh file1 file2 o $ loop1.sh file*, en lugar de aquéllos especificados en el script, como arriba. d. Cree un script llamado loop2.sh y colóquelo en ~/bin. El script utilizará el bucle until. Al ejecutarse, el script verificará para ver si un usuario, especificado como argumento del script, está loggeado. Si el usuario especificado no está actualmente loggeado, el script mostrará el mensaje “<specified user> is not logged on” (“<el usuario especificado> no está loggeado”) y “dormirá” durante cinco segundos antes de intentar nuevamente. Una vez que el usuario especificado se loggea, el script mostrará el mensaje “<specified user> is logged on”. e. Pruebe el script loop2.sh en una ventana de terminal utilizando el nombre de usuario del alumno como argumento para el script. Por ejemplo, $ loop2.sh user1. ¿Qué mostró el script? ___________________________ f. Ejecute nuevamente el script utilizando un nombre de usuario diferente. El nombre de usuario debe figurar en la lista del archivo /etc/password. Por ejemplo, $ loop2.sh user5. ¿Qué mostró el script? ________________________ g. Deje el script en ejecución y abra otra ventana de terminal. Utilizando la utilidad telnet, el alumno deberá loggearse a su propio sistema. Utilice $ telnet <nombre de host o dirección ip del alumno> para loggearse con el nombre de usuario especificado como argumento del script del alumno. En este ejemplo sería user5. ¿Qué mostró el script que se ejecuta en la primera ventana de terminal? ____________________________ h. Cree un nuevo script llamado counter1.sh y colóquelo en el directorio ~/bin. Introduzca las siguientes líneas de este script de bucle while: #!/bin/ksh # counts from 1 to 5 then displays “I can count!” # num=0 #initialize the count variable while [ $num -lt 6 ] #loop while $num is less than 6 do echo”number: $num” num=`expr $num + 1` #increment count by one done echo “I can count !” i. Ejecute el script, haga debug de ser necesario. ¿Contó el script de uno a cinco? _________ ¿Qué debe cambiarse en el script para que cuente de uno a cinco? ______________________________________________________________ Paso 10. Cerrar la ventana de terminal y hacer logout. Haga doble clic en el botón de raya del extremo superior izquierdo de la pantalla, luego haga clic en el ícono EXIT (SALIDA) del panel frontal. 8–8 Conceptos Fundamentales sobre UNIX 2.0—-Laboratorio 15.2.8 Copyright © 2002, Cisco Systems, Inc.