Objetivos:
• Programar scripts Bash para automatizar y apoyar el proceso de
administración del sistema de acuerdo a las necesidades y/o requerimientos
de la organización.
Beneficios:
Se podrán elaborar scripts que permitan automatizar y encadenar tareas
relacionadas con la administración del sistema, tareas repetitivas y generalmente
tediosas, etc.
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Índice
En GNU/LINUX hay varios tipos de SHELLS, ver la Figura Nº 2, cada una con sus
características propias, entre los más conocidos podemos nombrar:
BASH (/bin/bash) - El BASH es el SHELL por defecto en la mayoría de las
distribuciones de GNU/LINUX disponibles en la actualidad.
KORN SHELL (/bin/ksh) – Desarrollado por David Korn de los Laboratorios
AT&T Bell en el comienzo de la década del 80.
C SHELL (/bin/csh) – Desarrollado por Bill Joy en la Universidad de
Berkeley, California.
Cuando salimos de una “sesión de login”, BASH lee y ejecuta comandos desde el
archivo ~/.bash_logout, si es que este archivo existe.
http://dghubble.com/blog/posts/.bashprofile-.profile-and-.bashrc-conventions/
Para recibir información del usuario, BASH y otros programas emplean las
librerías readline e history. readline brinda facilidades para escribir comandos
con un teclado e history almacena los últimos comandos que el usuario haya
dado para facilitar su reutilización.
Algunas de las posibilidades que estas librerías ofrecen son:
Flechas o Control-p, Control-n - Para "navegar" sobre la historia de
comandos.
Completación con <TAB> - Se puede emplear la tecla <TAB> para
completar nombres de programas, de máquinas o de usuarios. Si hay
varias posibles completaciones un segundo <TAB> presentará la lista de
posibilidades.
Buscar comandos en la historia de comandos.
Control del tamaño del archivo de histórico: Se cuenta con dos variables de
entorno para ello, HISTSIZE y HISTFILESIZE, que indican el tamaño del archivo.
En el siguiente ejemplo podemos ver el uso de estas variables:
HISTSIZE=1000
HISTFILESIZE=1000
Con esto hacemos que el tamaño máximo del archivo de histórico sea de 1000
comandos o líneas.
Es posible utilizar la variable HISTCONTROL para hacer dos cosas: eliminar los
duplicados consecutivos con ignoredups y eliminar los duplicados sean o no
consecutivos con erasedups; tal como se muestra en los siguientes ejemplos:
export HISTCONTROL=ignoredups
o bien
export HISTCONTROL=erasedups
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Hay dos tipos de archivos de SHELL SCRIPTS: los basados en BASH y los
derivados de C. Ambos tipos de SHELL SCRIPT se escriben en un archivo de
texto al que se le otorgan permisos de ejecución. Una vez realizado este proceso
se podrá escribir en la consola o terminal el nombre del archivo y éste se ejecutará
como un comando.
Luego de esta línea se escribirán los comandos que queremos que ejecute
nuestro SCRIPT.
script. En este caso usamos el SHELL /bin/bash. Esto quiere decir que se
invocará al SHELL BASH para interpretar estos comandos y ejecutarlos.
Alumno DUOC
[alumno@localhost ~]$ unset msg
[alumno@localhost ~]$ echo $msg
[alumno@localhost ~]$
Existen dos áreas de memoria en los SHELLS para almacenar variables: el área
local de datos y el entorno o ambiente. Podemos visualizar el contenido de ambas
áreas a través del comando set.
[alumno@localhost ~]$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05a" [2]="0" [3]="1“…
BASH_VERSION='2.05a.0(1)-release'
COLUMNS=95
...
Por defecto, las variables utilizadas en un SHELL son locales, es decir, son
conocidas solo por ese SHELL.
Pero si se abre otro SHELL a partir del que estamos, estos nuevos “SUBSHELLS“
desconocen el valor de las variables que hemos asignado anteriormente. En
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Además de las variables de SHELL propias del entorno o ambiente, las definidas
por el usuario y los parámetros posicionales en un SHELL existen otra serie de
variables cuyo nombre está formado por un carácter especial, precedido por el
habitual símbolo $. Estas variables reciben el nombre de VARIABLES
PREDEFINIDAS.
clear
echo -e “Ingresar su nombre: \c”
read nombre
echo -e “hola $nombre\n”
Los argumentos “\c” y “\n” son interpretados por la opción -e de echo: “\n”
corresponde a un salto de línea y “\c” suprime el carácter salto de línea.
La orden read permite leer valores desde la entrada estándar y asignarlos a las
variables definidas en el SHELL. La instrucción read también puede leer
simultáneamente varias variables, tal como se muestra en el siguiente ejemplo:
read var1 var2 var3 …
El último resultado del ejemplo anterior se debe a que BASH sólo utiliza enteros
en sus respuestas.
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Para operaciones con reales se debe usar el programa bc; a modo de ejemplo
considere:
[alumno@localhost ~]$ echo 3/4 | bc -l
0.75
bc se incluye con todas las distribuciones LINUX como estándar, así como en casi
todas las UNIX.
Los resultados de cálculos en algunos formatos propietarios de bc tienen hasta 99
dígitos decimales antes y después del punto decimal. Este límite se ha superado
mucho en GNU bc, en al menos varias decenas de miles!!!.
bc acepta entrada de datos desde archivos y desde la entrada estándar, esto nos
permite dirigir los datos para hacer cálculos muy rápidamente.
Esto se puede configurar declarando scale antes de hacer los cálculos, tal como
se muestra en el siguiente ejemplo de división:
[alumno@localhost ~]$ echo "scale=25;57/43" | bc
1.3255813953488372093023255
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Hay que notar que las condiciones en BASH se pueden comprobar con test, tal
como hemos visto anteriormente, y también usando [ ].
if test condición
then
sentencias_1
else
sentencias_2
fi
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Si test evalúa la condición como “verdadera” se ejecutan las sentencias del IF, es
decir, el grupo de ordenes sentencias_1. Si test determina que la condición es
“falsa” se ejecutan las sentencias del ELSE, es decir, el grupo de ordenes
sentencias_2; tal como se muestra en la Figura Nº 3.
if test condición
then
sentencias
fi
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
#!/bin/bash
clear
read num
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
then
else
fi
#!/bin/bash
clear
read arch
if test –f $arch
then
more $arch
else
fi
case $opción in
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
opc_1) comandos;;
opc_2) comandos;;
…..
*) comandos;;
esac
#!/bin/bash
clear
read num
resto=$(expr $num % 2)
case $resto in
esac
Esto se hace para evitar que una vez se haya ejecutado un conjunto de órdenes,
se continúe con la ejecución de las órdenes de las siguientes opciones.
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
#!/bin/bash
clear
read arch
case $arch in
gcc $arch;;
esac
#!/bin/bash
clear
echo –e “\n\n\t\t\tMENU\n”
read opc
case $opc in
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
1) startx kde;;
2) startx gnome;;
3) exit;;
esac
Las sentencias del WHILE se ejecutarán mientras la condición evaluada con test
se mantenga en “verdadero”; cuando la condición alcance el valor de verdad
“falso” el ciclo WHILE dejará de ejecutarse. Una vez finalizado el ciclo WHILE, el
control de la ejecución del SCRIPT es pasado a la siguiente instrucción después
del bloque del WHILE. Ver Figura Nº 1.
i=1
sum=0
while test $i –le $num
do
sum=$(expr $sum + $i)
i=$(expr $i + 1)
done
echo –e “La suma de 1 a $num es: $sum\n”
#!/bin/bash
path=$PATH
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
while [ $path ]
do
echo ${path%%:*}
if [ ${path#*:} = $path ]
then
path=
else
path=${path#*:}
fi
done
Podemos usar el ciclo WHILE para leer todas las líneas de archivo.txt, tal como se
muestra en el siguiente ejemplo:
#!/bin/bash
while read línea
do
echo –e "$línea\n"
done < archivo.txt
Dos órdenes sencillas que pueden ser utilizadas, por ejemplo dentro de los ciclos,
son true y false. Como sus nombres lo indican, true siempre devuelve un valor
cierto (cero), y false siempre devuelve un valor falso (distinto de cero).
La sentencia true usualmente se utiliza junto con WHILE para construir ciclos
infinitos, por ejemplo, en la implementación de un menú de opciones:
#!/bin/bash
clear
while true
do
clear
echo “\t\t**********************\n\n”
read opc
done
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
#!/bin/bash
while true
do
clear
read num
then
break
fi
done
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
En el ejemplo anterior, se ingresan números (TODOS los que uno quiera, pero no
nulos) hasta cuando se ingresa cero, en ese instante el ciclo infinito termina de
ejecutarse, pues se ejecuta la sentencia break.
Si existen varios ciclos anidados, break terminará la ejecución del último que se
ha abierto. Es posible salir de n niveles de ciclo mediante la instrucción break n.
La instrucción continue reinicia el bucle con la próxima iteración dejando de
ejecutar cualquier orden posterior en la iteración en curso.
do
sentencias
done
La lista_de_valores del ciclo FOR también puede contener comodines (como por
ejemplo, el “*”). A modo de ejemplo, el siguiente SCRIPT muestra en pantalla la
lista de los archivos del directorio actual:
#!/bin/bash
for archivo in *
do
echo –e $archivo
done
Notar que para recorrer los argumentos recibidos por el SCRIPT, lo adecuado es
utilizar $@ entre comillas, es decir, usar “$@”.
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
do
if [ -x $archivo ]; then
echo –e $archivo
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
fi
done
#!/bin/bash
do
echo –e $i
done
Por último, podemos usar el ciclo FOR para leer todas las líneas de un archivo, tal
como se muestra en el siguiente ejemplo:
#!/bin/bash
oldIFS=$IFS
IFS=$'\n'
do
echo –e "$línea\n"
done
IFS=$old_IFS
do
sentencias
done
El ciclo UNTIL se ejecuta hasta que la evaluación de la condición con test alcance
“verdadero”. Según esto último, UNTIL se puede interpretar como ejecutar varias
veces un comando hasta que tenga éxito.
num=0
do
read num
done
#!/bin/bash
cont=10
do
cont=$(expr $cont - 1)
echo –e $cont
done
do
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
sentencias
done
do
echo $opt
then
exit
fi
done
#!/bin/bash
touch "$Salir"
select archivo in *; do
case $archivo in
"$Salir") exit;;
esac
done
rm –f "$Salir"
Esto permitirá organizar un SCRIPT en unidades lógicas de manera que sea más
fácil mantenerlo y programarlo (y entenderlo), sin necesidad de estar repitiendo
múltiples veces una misma porción de código.
Las funciones de BASH son una extensión de las funciones que existen desde el
BOURNE SHELL.
comandos_de_la_función
…..
}
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
nombre_de_función(){
comandos_de_la_función
…..
function Listar(){
if test –d $1
then
ls –l $1
fi
#PRINCIPAL
clear
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
read dir
#!/bin/bash
function Salir(){
exit
function Saludo(){
#PRINCIPAL
clear
function suma(){
c=$(expr $1 + $2)
return $c
#PRINCIPAL
echo –e “suma=$?\n”
>}
> exit
>}
declare –f salir
declare –f saludo
Notar que para “entrar” las líneas de la función se debe presionar <CTRL> +
<RETURN>.
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
Podemos ver que funciones tenemos definidas en una sesión usando el comando
declare –f. El SHELL imprime las funciones, y su definición, ordenadas
alfabéticamente. Si preferimos sólo el nombre de las funciones podemos usar el
comando declare –F. Si una función tiene el mismo nombre que un SCRIPT o
ejecutable, la FUNCIÓN tiene preferencia. Para borrar una FUNCIÓN podemos
usar el comando unset –f nombre_función.
function impParam(){
#PRINCIPAL
clear
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
function impParam(){
#PRINCIPAL
clear
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
$1=hola
Las variables por defecto son globales en BASH, por lo que si queremos que una
variable sea local, tenemos que definirla como local dentro de la función:
func(){
Por último, las variables globales también se pueden definir dentro de una
FUNCIÓN.
#!/bin/bash
function f1(){
v1=25
local v2=57
function f2(){
echo –e “v1=$v1”
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
#PRINCIPAL
f1
f2
echo –e “v1=$v1”
echo –e “v2=$v2”
#!/bin/bash
function impParam(){
}
Vicerrectoría Académica
Dirección de Servicios Académicos
Subdirección de Servicios a Escuelas
#PRINCIPAL
clear
function saludar(){
echo –e “Hola\n”
function salir(){
exit
#!/bin/bash
source librería.sh
…..
6.- Resumen
Las SENTENCIAS CONDICIONALES son las que nos permiten decidir por
un camino, entre dos ó más posibles, dada una condición.
until – Permite ejecutar una serie de comandos hasta que una determinada
condición se cumpla.
6.- Bibliografía
[1] Jang, Michael; RHCSA/RHCE Red Hat Linux Certification Study Guide, 6th
Ed.; McGraw-Hill, 2011.
[2] Van Vugt, Sander; Red Hat Enterprise Linux 6 Administration: Real World
Skills for Red Hat Administrators; John Wiley & Sons, 2013.
[3] Ghori, Asghar; Red Hat certified system administrator & Engineer: Training
guide and a quick deskside reference, Exams EX200 & EX300; Endeavor
Technologies Inc.; 1 edition, 2012.
[6] Garrels, Machtelt; Bash Guide for Begginers. Disponible online en:
http://linux.die.net/Bash-Beginners-Guide/
[7] Hill, Roger; Bash scripting for beginning system administrators. Disponible
online en: http://www.ibm.com/developerworks/aix/library/au-getstartedbash/