Está en la página 1de 12

Laboratorio de Redes

Introduccin a Shell Script


Una de las principales ventajas de GNU/Linux sobre otros sistemas
operativos es la capacidad de crear scripts hechos a la medida que ejecuten
cualquier funcin que se pueda realizar en la consola. Es decir, si el usuario
manualmente consulta un directorio o ejecuta ciertos programas, con un
script el usuario puede automatizar el proceso a la medida que necesita.
Un Script (o guion) para BASH es un archivo de texto que contiene una
sucesin de comandos de Shell que pueden ejecutar diversas tareas de
acuerdo al contenido del texto del guion. De esta forma pueden
automatizarse muchas acciones para alguna necesidad particular o para la
administracin de sistemas. El guion debe escribirse en un orden lgico
pues Bash ejecutar el guion en el orden en que se escriben las lneas, de la
misma forma que cuando se realiza una tarea cualquiera por una persona,
por ejemplo; primero hay que poner la escalera y luego subirse. (Wiki
Doc.Ubuntu)
En palabras sencillas, si hay algo que puedas hacer en la consola, lo puedes
poner en un Script. Estos scripts, no son propiamente lenguajes de
programacin y se ejecutan lnea por lnea hasta hallar un error o terminar
de forma exitosa. Al poder ejecutar cualquier comando de consola nos
permite incluso ejecutar dentro de un script programas y comandos hechos
en diferentes lenguajes de programacin para un resultado en particular. Por
ltimo, Los scripts aceptan ciertos estatutos como ciclos de repeticin (For,
While) y de condicin (IF, ELSE) adems de cierto nivel de declaracin de
variables.
A lo largo de esta prctica, se dar una introduccin extremadamente
bsica para el manejo de scripts en Ubuntu.
1 - Tipo de Shells
Durante la prctica de introduccin a sistemas GNU/Linux el alumno ya
habr utilizado SHELL. Ya que se trata de la lnea de comandos o consola
(SHELL).
En un entorno Linux (moderno) Existen una gran variedad de Shells cuyas
diferencias radican en la sintaxis pero no es objetivo de esta prctica
profundizar en ellos. Usualmente, el Shell que se halla por defecto es BASH
y ser para este Shell los scripts que se creen durante este laboratorio.
Actividad de laboratorio:
Realizaremos una bsqueda de cuntos tipo de shells soporta el Sistema
Operativo GNU/Linux que este manejando. Para ello ejecute el siguiente
comando:
cat /etc/shells
Y anote a continuacin los shells que aparezcan:
_____________________sh____________________________________________

_____________________dash____________________________________________
_____________________bash____________________________________________
_____________________rbash____________________________________________
_________________________________________________________________
2- Diseo de un script
Para empezar a crear un script, lo primero que se necesita es indicar que
tipo de sintaxis se utilizara, de lo contrario se corre el riesgo de ejecutar un
script con un Shell distinto provocando errores de sintaxis que elimine su
ejecucin. Para la definicin del script, la primera lnea del mismo es dicha
definicin. Para el laboratorio, todo script que se realice debe empezar con
la siguiente lnea:
#!/bin/bash
El uso de #! es un caso especial que solo debe aparecer una vez. Despus
de su primera aparicin, si volviera a aparecer causara conflictos en el
script. El uso de # (sin el signo de admiracin) sirve para identificar que
se trata de una lnea de comentario.
Una vez el script este diseado segn las necesidades que se requiera, se
necesita que el mismo sea ejecutable. Todo archivo en Linux se considera un
archivo de texto por defecto pero no son ejecutables. Para volverlo
ejecutable, utilizaremos el comando chmod.
Actividad de laboratorio:
2.1 - Crear el archivo
Cree un archivo de texto de nombre: Ejemplo.sh cuyo contenido sea el
siguiente:
#! /bin/bash
Cat /etc/passwd | grep redes
Como recordara de la prctica pasada, el comando cat /etc/passwd | grep
redes fue utilizado para desplegar todo los usuarios que contuvieran
redes. En este primer ejemplo, pondremos dichos comandos en un script.
NOTA: la extensin .sh no es necesario, se ha utilizado para facilitar que el
usuario diferencie con relativa facilidad un archivo cualquiera de uno de
script.
2.2 - Hacer ejecutable el archivo
Utilizaremos el siguiente comando
Chmod u+x Ejemplo.sh
U Indica User y el +x hace que se active la opcin de ejecutable para el
usuario. Es decir, los dems permisos (R, W) no se ven afectados y
G(rupos) , O(tros) no son alterados. Existen distintos modos de usar el

comando chmod, pero este es el modo ms seguro al solo modificar una


propiedad (la que necesitamos) de un solo miembro de UGO.
2.3- Ejecutar el script
Todo archivo ejecutable, se puede realizar anexando el prefijo ./ a su
nombre. De hecho, sin esta indicacin Linux no intentara ejecutar el script.
Ejecute el comando:
./Ejemplo.sh
El resultado es distinto a la prctica pasada? Por qu?
______________________________________________________________________

2.4 Variables
Como se ha mencionado, un script puede manejar variables, entre las ms
usuales estn las que serviran como argumentos (Entradas obligatoria u
opcionales de un programa) adems de las variables internas del programa.
Las variables que se obtengan de los argumentos del script tienen la
siguiente nomenclatura:
$0 Generalmente, es el nombre del script Shell ejecutado.
$1 Primer argumento del script
$2 Segundo argumento del script
$3
$4
$# Total de argumentos que el script recibi.
$@ Un string conteniendo todo los argumentos que introdujo el usuario.
Generalmente se utiliza $# para garantizar que el programa fue utilizado
con suficientes argumentos antes de seguir con la ejecucin del mismo y los
dems para ir accediendo a las distintas variables que el usuario introdujo.
Una caracterstica importante de las variables es que estas pueden contener
todo tipo de valores, a diferencia de la mayora de los lenguajes de alto nivel
que definen el tipo de variable. Eso significa que un desarrollador de Bash
Script tiene que tener cuidado a la hora de manipular las variables de que
su contenido es el esperado.
No es objetivo de este laboratorio profundizar ms en el uso de las
variables.
3- Observaciones de los scripts
Probablemente, todava no le quede claro al alumno las capacidades de un
script, pero estos son extremadamente poderosos ya que permite una gran
gama de ejecuciones y de fcil personalizacin permitiendo que el usuario
cree sus propias herramientas de uso diario.

Generalmente, al crear un script dos elementos deben de tenerse en


cuenta:
1. Las entradas y salidas no deberan verse alteradas. Es decir, todava
debera de recibir una entrada estndar y salida estndar, de tal forma el
mismo usuario pudiese manipularlas como lo hara con cualquier otra
funcin predefinida.
2. Un script debe ser flexible en los parmetros de entrada pero estricto en
los de salida. Es decir, un script podra recibir parmetros basura (Respecto
a lo que necesita) y no debe de generar una salida. Pero por ningn motivo
debe de generar basura en la
salida.
Un excelente ejemplo puede ser la manipulacin de archivos con texto
donde se dese dar un nuevo formato a la informacin o incluso desplegar
solo ciertos datos. Sobre todo hoy en da que la mayora de los diferentes
tipos de archivos de texto manejan XML. Esto se debe a las herramientas de
filtrado como GREP y AWK (la primera en menor medida).
Un segundo ejemplo, es cuando se requiere ejecutar ciertas secuencias de
montado de dispositivos, re-compilacin de cdigos y programas con cierta
regularizacin.

4- Scripts de ejemplo
El objetivo de este inciso ser la lectura del script y su ejecucin para ir
acostumbrado al alumno respecto al funcionamiento de los mismos.
Ejemplo 1:
Un modo de creacin de un men :
ba
Ejemplo 2:
Seleccin de un nmero aleatorio
secretNumber=$(( ((`date +%N` / 1000) % 100) +1 ))
guess=-1
while [ "$guess" != "$secretNumber" ];
do
echo -n "I am thinking of a number between 1 and 100. Enter your
guess:"
read guess
if [ "$guess" = "" ]; then
echo "Please enter a number."
elif [ "$guess" = "$secretNumber" ]; then
echo -e "\aYes! $guess is the correct answer!"
elif [ "$secretNumber" -gt "$guess" ]; then
echo "The secret number is larger than your guess. Try again."
Else
echo "The secret number is smaller than your guess. Try again."

fi
done

Ejemplo 3:
Validar si una serie de hosts estn disponible en la red.
La secuencia de pings son de la 10.17.117.1 a la 10.17.117.20 es decir, se
revisan 20 dispositivos en la red interna del campus.

#!/bin/bash
is_alive_ping()
{
ping -c 1 $1 > /dev/null
[ $? -eq 0 ] && echo Node with IP: $i is up.
}
for i in 10.17.117.{1..20}
do
is_alive_ping $i & disown
done

Ejemplo 4:
Arreglos
Considere los arreglos como valores guardados en una lista pre-existente
array=(red green blue yellow magenta)
len=${#array[*]}
echo "The array has $len members. They are:"
i=0
while [ $i -lt $len ];
do
echo "$i: ${array[$i]}"
let i++
done
5- Ejercicios:
Ejercicio 1
Utilice el script del ejemplo 3 para crear un script que haga una serie de
pings predefinidos a las mquinas de sus compaeros (y solo a ellas). Puede
basarse en el ejemplo 1 sustituyendo el men de colores por direcciones IP.
Ejercicio 2
Cree un script que permita crear las siguientes carpetas de forma
automatizada:
~/Sesion3

~/Sesion3/Alumno1
~/Sesion3/Alumno1/Califas
~/Sesion3/Alumno3
~/Sesion3/Alumno4
Ejercicio 3
Cree un script similar al ejercicio 2, pero que te pida el nombre las de
carpetas y que pueda ser ejecutado desde cualquier directorio.
Curiosidades
Los siguientes scripts son una recopilacin de la red con el nico propsito
de mostrar algunos usos posibles a los Scripts en Linux.

Crear un rombo de caracteres


#!/bin/bash
#
# Linux Shell Scripting Tutorial 1.05r3, Summer-2002
#
# Written by Vivek G. Gite <vivek@nixcraft.com>
#
# Latest version can be found at http://www.nixcraft.com/
#
MAX_NO=0
echo -n "Enter Number between (5 to 9) : "
read MAX_NO
if ! [ $MAX_NO -ge 5 -a $MAX_NO -le 9 ] ; then
echo "I ask to enter number between 5 and 9, Okay"
exit 1
fi
clear
for (( i=1; i<=MAX_NO; i++ ))
do
for (( s=MAX_NO; s>=i; s-- ))
do
echo -n " "
done
for (( j=1; j<=i; j++ ))
do
echo -n " ."
done
echo ""
done
###### Second stage ######################
##
##
for (( i=MAX_NO; i>=1; i-- ))
do

for (( s=i; s<=MAX_NO; s++ ))


do
echo -n " "
done
for (( j=1; j<=i; j++ ))
do
echo -n " ."
done
echo ""
done
echo -e "\n\n\t\t\tI hope you like it my stupidity (?)"
#
# ./ch.sh: vivek-tech.com to nixcraft.com referance converted using this
tool
# See the tool at http://www.nixcraft.com/uniqlinuxfeatures/tools/
#
Canal IRC
Este script permite la conexin a un canal IRC
#!/bin/bash
#
# configuration
nick="`basename $0`$$"
# nickname name="$0 $*"
# real name chan="
#sh
#bash"
# channels to join mode="+i"
# irc mode
# end of configuration
# use our login name if there's no nickname nick="${nick:-$USER}"
# see if we can find a realname for our nickname name="${name:-`grep
$nick /etc/passwd | cut -d : -f 5`}"
host="$1"
port="$2"
# redirect error messages to file `irc-errors' exec 3<> irc-errors 2>&3if [ ! "$2" ]; then
echo "usage: `basename $0` [hostname] [port]"
exit 1
fi
# try to connect
if ! exec 3<> /dev/tcp/$host/$port; then
echo "`basename $0`: unable to connect to $host:$port"
exit 1
fi
# duplicate standard input and output with the newly created socket exec
0<&3 1>&3# register to the server

echo "USER $nick ${mode:-+iw} $nick :$name"


echo "NICK $nick"
# join channels
for c in $chan;
do
echo "JOIN $c";
done
while read;
do
set -- ${REPLY//$'\r'/}
# answer the critical ping request
# otherwise the server will disconnect us [ "$1" == "PING" ] && echo
"PONG $2"
# your code should go here
done
exec 1<&- 2<&-

Ejecutar un comando en cada directorio


# Title : global - execute command in every subdirectory
# Author : Heiner Steven <heiner.steven@odn.de>
# Date : 1994-09-29
# Requires :
# Category : File Utilities
# SCCS-Id. : @(#) global 1.3 03/12/19
##############################################
############################
# Description
#
##############################################
############################ PN=`basename "$0"`
# program name
VER='1.3'
usage ()
{
echo >&2 "$PN - execute command in subdirectories, $VER (stv '94)
usage: $PN [-v] command [argument ...]
-v verbose, print current path
The given command is executed in every subdirectory of the current
directory, depth first. At last it is executed in the current
directory, too.
If the command contains embedded blanks, it must be enclosed in
quotation marks \"...\" or '...'."
exit 1
}
err ()

{
for i
do echo "$PN: $i" >&2
done
}
fatal () { err "$@"; exit 1; }
msg () { [ "$silent" = no ] && err "$@"; }
MyPath=$0
# Export "silent" to subshells, because parameters to the
# invoking shells are not passed to the subshells : ${silent:=yes}
# yes/no, may be set from calling shell export silent
while [ $# -gt 0 ]
do
case "$1" in
-v) silent=no;;
--) shift; break;; # End of parameter list
-h) usage;; -*) usage;;
*) break;;
# Command
Esac
Shift
done
[ $# -lt 1 ] && usage
for i in *
do
[ -d "$i" ] || continue
cd "$i"
"$MyPath" "$@"
# recurse into subdirectories
cd ..
done
msg "`pwd`"
eval "$@"

Crear un listado de correos

#!/bin/bash
#Version: 1.0.1 ( 28/01/11 )
#Objetivo: Ensear la forma de leer ORIGENs y manejo de strings
# Elementos clave: "Un shell debe ser flexible en los parametros de entrada
pero estricto en los de salida
# Entrada: Una lista de matriculas (alfa numerico), salida:
A0#######@itesm.mx
# LA parte dinamica es de 9 caracteres, la parte estatica es de 9
# en total cada linea del ORIGEN resultante debera tener 18 caracteres
ARGS=1
#Max de argumentos que puede recibir
ORIGEN="entrada.txt" ; DESTINO="matriculas.txt" #Entrada y Salida no
estandar del bash Match=""
#Variable usada para hacer
busqeudas con grep

Line=$@
EXPREG1="^A0[0-9]*"
#ER utilizadas para buscar los posibles
formatos
EXPREG2="^[0-9]*"
# de las matriculas escritas por los alumnos.
EXPREG3="^A[0-9]?@itesm.mx"
LeerORIGEN()
{
#echo "" > "$DESTINO" #Un archivo temporal es creado para ir guardando
lo exitoso
#El for avanzara en cada Palabra hallada en lo que regrese cat $ORIGEN
for WORD in `cat $ORIGEN`
do
#Aqui es donde buscaremos WORD, en teoria puede ser Alfa
numerico o solo numerico
#Iremos descartando, primero A0#######
Match=`echo "$WORD" | grep -xwi "$EXPREG1"`
if [ "$Match" = "" ]
then
#echo "No es el primer formato "
#Puede estar ya bien en el formato definitivo
Match=`echo "$WORD" | grep -xwi "$EXPREG3"`
if [ "$Match" != "" ]
then
#La longitud es necesaria de checar
if [ "${#Match}" -eq 18 ]
then
#Un correo en el formato y longitud
debido
#echo "Un correo hallado" "$EXPREG3"
": " $Match
echo "$Match" #>> "$DESTINO"
fi
else #Puede ser meramente numero (Sin A0)
Match=`echo "$WORD" | grep -xwi "$EXPREG2"`
if [ "$Match" != "" ]
then
#LA longitud es un problema... A00787620, A0-1787620 y A00-787620 son
# validas, por lo tanto ifelse
if [ "${#Match}" -eq 8 ]
then
#echo "Una matricula escrita
informalmente""$EXPREG2" ": " $Match echo "A""$Match""@itesm.mx" #>>
"$DESTINO"
elif [ "${#Match}" -eq 7 ]
then
#echo "Una matricula escrita
informalmente""$EXPREG2" ": " $Match

echo "A0""$Match""@itesm.mx" #>>


"$DESTINO"
elif [ "${#Match}" -eq 6 ]
then
#echo "Una matricula escrita
informalmente" "$EXPREG2" ": " $Match echo "A00""$Match""@itesm.mx"
#>> "$DESTINO"
Fi
Fi
Fi
else
#OJO: Espacios en blanco todavia pasan y longigutdes
largas tambien
# Debemos garantizar que solo se registren longitud de 9
caracteres
# ${#Match} es uno de las tantas opciones para obtener
longitud de strings
if [ "${#Match}" -eq 9 ]
then
#echo "Una matricula hallada" "$EXPREG1" ": "
$Match
echo "$Match""@itesm.mx" #>> "$DESTINO"
fi
fi
done
}
##############################################
#############
####### Equivalente a un MAIN ######################
##############################################
#############
#echo $
#
#echo $@
#echo $1
#echo "BASH para convertir matriculas a cuentas de @itesm.mx"
#Validamos argumentos de entradas
#Para 1.0 se ocupa un argumento a fuerzas
if [ $# -eq "$ARGS" ]
then
ORIGEN=$1
#echo "Archivo de origen: " "$ORIGEN"
Else
echo "$0" " Error : Falta el archivo de entrada "
exit 1
fi
# Checamos meramente si existe el ORIGEN con el que se desea trabajar s
if !( test -e $ORIGEN )
then

echo "$0" " Error : No hay ORIGEN de entrada disponible"


exit 1
else
#echo "Leyendo el ORIGEN " $ORIGEN
LeerORIGEN $ # $1
fi
exit 0
Trabajos citados

LinuxConfig. (2010, November 9). Bash Script for scan and monitoring
network. Retrieved Agosto 2011, from LinuxConfig.org:
http://linuxconfig.org/bash-scripts-to-scan-and-monitor-network
Lutus, P. (2006). Bash Shell Programming in Linux. Retrieved Agosto 2011,
from arachnoid.com:
http://www.arachnoid.com/linux/shell_programming.html
Wiki Doc.Ubuntu. (n.d.). Script. Retrieved Agosto 2011, from doc.ubuntu-es:
http://doc.ubuntu-es.org/Script