11/04/2008


Programación en Bash

Exelente manual para la programación en bash, desde xtech.com.ar

Introducción

Linux, así como la mayoría de los UNIX, utilizan shell scripts para realizar una infinidad de tareas. Un shell script es un programa que se escribe con una sintaxis particular, en un archivo de texto plano, para que sea interpretado por un shell, en este caso /bin/bash.

Un shell script es básicamente un programa que llama a otros programas, con la posibilidad de hacer algun tipo de procesamiento propio (como control de flujo, operaciones matemáticas simples, etc).

Por lo tanto la forma de crear un shell script es hacer un archivo con nuestro ya querido vi:

vi holam

Luego lo llenamos con las instrucciones que deseamos. Por ejemplo:

#!/bin/bash
echo "Hola mundo!"
# Esto es por costumbre utilizado como ejemplo del primer programa.
# Se dice que trae suerte!

Luego le damos permisos de ejecución a ese archivo:

chmod +x holam

Y de esta manera ya tendremos listo un shell script que se ejecuta de la siguiente forma:

./holam

Debemos destacar la primera linea de nuestro script bash:

 #!/bin/bash

esta línea le indica al sistema que el script será interpretado por el programa que se encuentra a continuación de #!, en este caso, /bin/bash

Las últimas dos líneas son comentarios

 # Esto es por costumbre utilizado como ejemplo del primer programa.
# Se dice que trae suerte!

Los comentarios comienzan con # y se extienden hasta el final de la línea. Es muy útil ir comentando el código que uno escribe, para recordar qué realizan ciertas funciones o algoritmos, y otra persona pueda comprender el funcionamiento de nuestro script.


Variables

Las variables en un script BASH son simplemente identificadores, sin tipo. Para asignar un valor a una variable, se utiliza el operador =, por ejemplo:

[jose@xtech experto]$ MIVARIABLE=4

Por convención, los nombres de las variables se usan en mayúsculas, aunque no es obligatorio.

Para usar el contenido de la variable, dentro de un script, se usa el operador $. Por ejemplo:

[jose@xtech experto]$ echo $MIVARIABLE
4
[jose@xtech experto]$

Para utilizar el contenido de una variable, seguida de un texto, debemos usar las llaves {}

Consideremos este ejemplo:

 ARCHIVO="/tmp/ej"
mv $ARCHIVO $ARCHIVO-bak

En este caso, bash interpretaría a $ARCHIVO y $ARCHIVO-bak como dos variables distintas, para evitar esto debemos reescribirlo de esta manera:

 ARCHIVO="/tmp/ej"
mv $ARCHIVO ${ARCHIVO}-bak

Comillas

En el shell, el espacio, o el tab, son separadores. Es decir, que cuando al shell le indicamos

ls -l hola que tal

Lo interpreta como que le pedimos que nos de información sobre tres archivos, llamados: hola, que, y tal.

Si en realidad, lo que queríamos, era información sobre un archivo llamado "hola que tal", entonces hay varias maneras de indicarle al shell que los espacios entre esas palabras no deben ser separadores.

Escape ( \ )

Hay un caracter de escape, que indica al shell que el siguiente carácter no es especial. Y es la barra invertida. Por lo tanto, podríamos obtener la información del archivo "hola que tal" de la siguiente forma:

ls -l hola\ que\ tal

Los espacios no son especiales, no son separadores, y "hola que tal" es una sola palabra.

Algunos caracteres especiales más:

\ @ ! | < > [ ] { } ( ) ? * $ ' ^ ` " # & ;

Por lo tanto, si queremos incluir la \ en alguna parte, entonces debemos ponerla 2 veces (\\), la primera para decirle a BASH que no tome como carácter especial lo que sigue y la segunda como ese carácter que queremos incluír. Esto es muy común en casos como:

cd algún\ directorio\ con\ espacios

Comillas dobles ( " " )

Las comillas dobles hacen que los espacios entre las comillas no sean especiales. Por lo tanto, podríamos haber utilizado:

ls -l "hola que tal"

Todos los otros carácteres siguen siendo especiales.

Comillas simples ( ' ' )

Las comillas simples logran que ningún caracter (salvo la comilla simple misma) sea especial. Por ejemplo, si quisieramos crear un archivo que se llame *@$&, lo debemos hacer rodeándolo de comillas simples:

touch '*@$&'

Si queremos poner una comilla simple, debemos "escaparla". Para crear un archivo llamado que'tal, deberíamos hacerlo así:

touch 'que\'tal'

Ya que si no lo hacemos, la segunda comilla "cierra" la primera!

Comilla invertida ( ` ` )

Las comillas invertidas son más raras. Deben rodear un comando. Ese comando será ejecutado, y lo que ese comando imprima reemplazará al contenido de las comillas invertidas. Tal vez lo más sencillo sea un ejemplo:

[jose@xtech experto]$ ls
experto.aux experto.log experto.lyx experto.pdf experto.tex
experto.dvi #experto.lyx# experto.lyx~ experto.ps experto.toc

[jose@xtech experto]$ V=`ls`
[jose@xtech experto]$ echo $V
experto.aux experto.log experto.lyx experto.pdf experto.tex
experto.dvi #experto.lyx# experto.lyx~ experto.ps experto.toc
[jose@xtech experto]$

El uso más frecuente de las comillas invertidas es poder asignar el "resultado" de un comando a una variable.

Control de flujo

Esto refiere al cauce o flujo normal de los programas. No siempre hay un solo camino a seguir y estas proposiciones permiten que el programa realice distintas tareas, según las condiciones de las variables a interpretar.

"if"

El"if" es un proposición de control que verifica si es verdadera o falsa una condición.

Sintaxis:

if comando-condición
then
Comandos si la condición es verdadera
else
Comandos si la condición es falsa
fi

Es importante que la ubicación de las lineas se mantenga, ya que las proposiciones if/then/else/fi se controlan línea por línea. La parte else es opcional. En caso de querer hacer todo el control en una sola línea, las proposiciones deberán estar separadas por un punto y coma (;).

Los comandos que estén debajo del then se ejecutarán si la condición dio verdadera. Esto quiere decir que el valor de retorno de la condición fue 0 (cero). En caso contrario se ejecutarán los comandos que le siguen al else, si es que se utilizó esta proposición.

En la condición se puede poner un comando, donde la ejecución del mismo (su valor de retorno) definirá qué comandos (de qué proposición) se ejecutarán.

Si se verifica una condición, se deberán utilizar los corchetes para mayor comprensión.

Ejemplos:

(utilizando comandos) El hecho de entregar algo como salida se toma como condición lógica verdadera.

if ps ax | grep httpd | grep -v grep
then
echo "El web server está funcionando"
else
echo "El web server NO esta funcionando"
fi

(utilizando condiciones)

if [ -w /etc/passwd ]
then
echo "Tengo permisos de escritura en el archivo /etc/passwd"
else
echo "NO tengo permisos de escritura en el archivo /etc/passwd"
fi

Puede suceder que tengamos que testear mas de una condicion, para esto, podemos utilizar la siguiente estructura:

if condición1
then
Comando1
Comando2
elif condición2
then
Comando1
Comando2
else
Comando-por-defecto #Ninguna de las condiciones anteriores es verdadera
fi

Esta es una manera de abreviar varias estructuras if - then - else - if en una sola, pudiendo utilizarse más de dos condiciones.

La estructura de control if, es muy utilizada con test, que no es más que una operación de comparación, en las condiciones que se requieran.

"case"

El "case" es una proposición que puede analizar y validar varios casos (opciones) del valor de una variable.

Sintaxis

case variable in
patrón | patrón)
Comando;
Comando;
Comando;;

patrón | patrón)
Comando;
Comando;
Comando;;
*)
Comandos si ningún otro valor fue igualado;;
esac

El case es raramente usado, pero es muy eficiente en algunos casos.

Ejemplos:

case $mes in
ene*|Ene*)
echo "Mes de Enero";;
feb*|Feb*)
echo "Mes de Febrero";;
mar*|Mar*)
echo "Mes de Marzo";;
*)
echo "Algún otro mes!";;
esac

Ciclos

Los ciclos contienen secciones del programa que se repetirán una determinada cantidad de veces o hasta que alguna condición cambie.

for

El for debe ser el ciclo más utilizado, es muy práctico cuando se trabaja con shell scripts.

A diferencia de los lenguajes de programación más comunes, un ciclo for dentro de un shell script realiza una acción dada sobre cada uno de los elementos de una lista, y no sobre una variable que se va incrementando en cada ciclo.

La variable utilizada en el for (en este caso $i) es reemplazada por cada una de las palabras de la lista, en cada ciclo del for.

Sintaxis:

for i in lista de palabras
do
cuerpo del ciclo, $i tiene el valor de elementos sucesivos de la lista
done

Ejemplos:

for i in `ls -1 /tmp`
do
echo $i
rm -i $i
done

En este ciclo, el comando ls -1 /tmp, generará una lista de todos los archivos que existen en el directorio /tmp. Dentro del cuerpo del ciclo imprimimos el contenido de la variable y luego preguntamos si se desea borrar ese archivo (opción -i del comando rm).

while

Este ciclo utiliza la condición de terminación de un comando (valor de retorno) para controlar la ejecución de los comando dentro del ciclo. Termina la ejecución del ciclo, cuando el comando devuelve falso (algo diferente a 0).

Sintaxis:

while comando
do
cuerpo del ciclo ejecutado a condición de
que el comando devuelva verdadero
done

Ejemplos:

while sleep 60
do
who | grep daniel
done

En este ejemplo, cada 60 segundos (definidos por el comando sleep 60), verificará si el usuario daniel ha ingresado al equipo. En caso de que lo haya hecho, el listado del who saldrá por pantalla (cada 60 segundos).

until

Este ciclo se comporta de una manera muy similar al anterior, ya que define su control dependiendo del comando que ejecuta (si éste da verdadero, se sigue ejecutando el ciclo).

Sintaxis:

until comando
do
cuerpo del ciclo ejecutado a condición
de que el comando devuelva falso.
done

Ejemplo:

until who | grep daniel
do
sleep 60
done

En este ejemplo, a diferencia del ejemplo del ciclo while, el ciclo ejecuta primero el comando, de esta forma no es necesario esperar 60 segundos para saber si el usuario daniel esta logueado en el equipo (si el usuario esta logueado, el ciclo termina).

Argumentos

Los argumentos sirven para pasarle a un programa o una función valores desde la línea de comando.

Variable Descripción
$# Número de argumentos
$* Todos los argumentos del shell
$- Opciones suministradas al shell
$? Valor de retorno del último comando ejecutado
$$ Identificación del PID (número de proceso)
$0 Nombre del script
$1 Primer argumento
$n Argumento "n"

Ejemplo:

#!/bin/sh
#
# Programa que recibe argumentos y los imprime por pantalla
#
echo "\$*: $*"
echo "\$#: $#"
echo "\$0: $0"
echo "\$1: $1"
echo "\$2: $2"

Notas sobre el ejemplo:

En la líneas de impresión (echo), para imprimir el símbolo "$" (pesos) se tiene que anteponer el símbolo "\" (contra barra), sino el shell lo va a interpretar como una variable, y si esta existe imprimirá su contenido.

Funciones

Las funciones son un recurso esencial para la buena programación, permiten escribir una sola vez un pedazo de código que se repita varias veces en el script, y así, minimizar el margen de error y también la cantidad de líneas en el programa.

Para utilizarlas simplemente se hace un llamado a la función. Las funciones pueden estar dentro del mismo shell script, o en un archivo aparte. Cuando se escriben las funciones en un archivo aparte, es muy importante utilizar el comando "." (punto) para cargarlas en memoria. Si no se cargan en memoria de esta manera, las funciones no estarán disponibles.

Ejemplo:

#
# Cargando las funciones en memoria
#
. /home/jose/funciones/funciones-arch.sh

Uso

La sintaxis para utilizar funciones es muy sencilla y no agrega mayor dificultad. El modo de uso se remite a definir la función especificando el nombre y parentesis que abren y cierran. Todos los comandos que involucran la función se encierran con llaves.

Ejemplo:

(archivo: lib/arch.sh)

#
# Funciones para manipulación de archivos
#
borrar ()
{
arch=$1
if [ -z "$arch" ]
then
echo "No se recibió ningún archivo"
return 2
else
if [ -f "$arch" ]
then
if [ -w "$arch" ]
then
rm -i $arch
else
echo "No tengo permisos para borrar $arch"
fi
else
echo "$arch no es un archivo"
fi
fi
}

(archivo: principal.sh)

#!/bin/bash
#
# Programa ejemplo para el uso de funciones en shell script
#

#
# Cargo las funciones en memoria
#
. lib/arch.sh
dir=./
for i in $dir/*
do
borrar $i
done

Notas sobre el ejemplo:

(archivo: lib/arch.sh)

Esta función toma el archivo a borrar como argumento (arch=$1), verifica que se le haya pasado un argumento realmente (if [ -z "$arch" ]), que un archivo pasado como argumento sea regular (if [ -f "$arch" ]) y que tenga permisos de escritura. En todos los casos de falsedad responde con un mensaje avisando el problema.

(archivo: principal.sh)

El programa hace un ciclo con los archivos de un directorio específico (for i in $dir/*) y se los pasa como argumento a la función borrar.

Valores de retorno

Las funciones pueden devolver valores de error utilizando el comando "return ". En caso de que no se especifique un valor de retorno de esta forma, el valor retornado será el que retorne el último comando ejecutado dentro de la función. Desafortunadamente no es posible asignar el valor retornado en una sola línea, siempre es necesario utilizar la variable especial "$?".

Ejemplo:

#!/bin/sh

func () {
return $1
}

func 0
echo "ret: ($?)"
func 1
echo "ret: ($?)"
func 2
echo "ret: ($?)"
func 3
echo "ret: ($?)"

Variables locales a la función

Existe la posibilidad de utilizar variables locales a la función, esto significa que la variable solamente va a existir durante la ejecución de la función.

Para crear una variable local a la función se utilizar el operador "local ".

Ejemplo:

func () {
local x
x=$1
echo "Dentro de la función \$x vale ($x)"
}

echo "Antes de ejecutar la función \$x vale ($x)"
func HOLA!!
echo "Después de ejecutar la función \$x vale ($x)"

Operaciones Aritméticas

Existen varias formas de calcular valores dentro de un shell script. Tradicionalmente, estos cálculos se hicieron con programas externos, esto generaba un retardo inmenso en la ejecución del shell script.

Hoy los nuevos intérpretes traen la posibilidad de hacer cálculos internamente. Para esto se utiliza una sintaxis especial, y es muy importante que los valores de las variables que utilicen para hacer estos cálculos sean números únicamente.

Uso

La sintaxis para hacer operaciones aritméticas es la siguiente:

$[]

Las operaciones que se pueden realizar son:

  • suma $((1+1))
  • resta $((2-1))
  • multiplicación $((2*2))
  • división $((2/2])
  • otras como suma de bits, sacar el módulo, evaluación de igualdad, etc.

Ejemplo:

#!/bin/sh
#
# Operaciones aritméticas
#
x=2
tot=$[$x+1]
echo "tot: ($tot)"

bc

A veces hay conjuntos de herramientas que nos suenan y no las aprovechamos al máximo. Quizás una de esas sea bc. La calculadora que podemos usar desde la consola, que aparte de sumar y restar puede realizar cálculos con una precisión de varios decimales, cambiar de base numérica o programarla, etc. veremos como...

Si ejecutamos bc veremos:

$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.

Acá espera que trabajemos desde la entrada estándar, por ejemplo:

4+8
12
scale=3
27/68
.397
halt

Sabe sumar (y restar, dividir, multiplicar; sin problemas).

Variables

Si queremos que trabaje con decimales, asignaremos un valor a la variable scale.

scale=3
2/3
.666

También podemos hacer:

scale=9;2/3
.666666666

Al ser scale una variable más, podemos consultar su valor sencillamente escribiéndola:

scale
3
#o también usando print
print scale
3

Otro ejemplo de usos de variables podría ser:

scale=5
variable=3
100/variable
33.33333

Hay una variable especial llamada last, almacena el resultado de la última operación:

100/3
33.33333
last*2
66.66666

Cambios en la base numérica

Hay dos variables especiales que son ibase y obase que definen la base de entrada y de salida de los números, respectivamente.

Si queremos calcular el número 5 en base 10 (decimal) a base 2 (binario), haremos:

obase=2
5
101

Si queremos pasar de binario a hexadecimal:

obase=16
ibase=2
11111111
FF

Otras operaciones matemáticas

Podemos usar también sqrt, 2^3, etc.

Si queremos tener operaciones matemáticas más complejas tenemos que ejecutar el bc -l para cargar la librería matemática:

s (x)   Seno de x, en radianes
c (x) Coseno de x
a (x) Arcotangente de x
l (x) Logaritmo neperiano de x
e (x) Exponencial de x
j (n,x) Función de Bessel de un entero de orden n de x

Aplicación en un script

Si queremos pedir que el usuario teclee algo por teclado, la función es read. Por tanto.

variable=read()

Esperará que tecleemos algo y lo pondrá en variable.

También podemos hacer un programa en un archivo y ejecutarlo:

print "Hola\n"
print "Escribe tu año de nacimiento\n"
nacimiento=read()
edad=2003-nacimiento
print edad
print " años\n"
halt

Y lo ejecutamos con bc -q archivo.bc (el -q es para que no muestre el Copyright) estaremos preguntando el año nacimiento y mostrando la edad.

Ahora un ejemplo definiendo una función, pasándole un parámetro y retornándolo. Veremos que es totalmente intuitivo:

define mayor_edad(edad) {
if (edad <>= 18)
return 1
}

print "Dí tus edad\n"
edad=read()

if (mayor_edad(edad))
print "Eres mayor de edad\n"

if (!mayor_edad(edad))
print "Eres menor de edad\n"

halt

Un último ejemplo, con un for:

for (i=0;i<10;i++)> 

Observemos en la , para separar la variable y la cadena en el print.

Para salir

halt

Otra forma muy útil en los scripts es:

resultado=$(echo "scale=3;2/3" | bc)

Operaciones lógicas y de comparación


test

Para usar if podemos usar un nuevo elemento, los corchetes que evalúan las condiciones, esto esta basado directamente en test. Y éste nos sirve para comparar variables.

Por ejemplo:

-lt Menor que
-eq Igual que
-gt Mayor que
-le Menor o igual que
-ge Mayor o igual que
-ne No coinciden
-a Operador lógico and
-o Operador lógico or
!= Distinto

Sintáxis:

exp1 operador exp2

Uso de test:

test 8 -lt 9

Usando variables en test:

variable1=5
variable2=3
test $variable1 -gt $variable2

Otra forma muy útil de uso de test (si 3 es menor que 5):

[ 3 -lt 5 ]

O (si $HACER es distinto de 1):

[ $HACER != 1 ]

Ejemplo:

#!/bin/bash
variable1=5
variable2=3
[ $variable1 -lt $variable2 ]
echo $?

Aqui hemos evaluado dos variables para ver si la variable1 era menor que la variable2 y para ver el resultado hemos acudido a la “variable de retorno”, que nos mostrara 0 o 1.

Cuando necesitamos utilizar la negación, debemos usar el signo !

Ejemplo:

 if [ ! -x $FILE ]
then
chmod +x $FILE
else
echo "$FILE es ejecutable"
fi

Si el archivo no es ejecutable, le damos permiso de ejecución, sino, imprimimos el mensaje por pantalla

Interacción con el usuario

Muchos programas no serían factibles si no tuviéramos algún mecanismo para interactuar con el usuario, ya sea un simple "Presione Enter para continuar" o algo más sofisticado, como una lista de opciones de las cuales escoger.

Cuando el programa está escrito en shell, es muy sencillo lograr ambas cosas, utilizando dos herramientas: read y dialog.

read

El comando read es muy sencillo. Le indicamos que pida el valor de una variable al usuario, el usuario escribe una línea de texto (es decir, cualquier cosa hasta que presione enter), y la variable toma el valor que el usuario ingresó.

Ejemplo:

[jose@xtech experto]$ read V
Hola mundo!
[jose@xtech experto]$ echo $V
Hola mundo!
[jose@xtech experto]$

Si deseamos sólo un "Presione enter para continuar" es exactamente lo mismo, simplemente ignoramos el valor de la variable :-)

dialog

Dialog es un programa que crea una "interfaz" para que el usuario interactúe, y entrega por la salida estándar el resultado de la acción del usuario, variable $?.

Puede producir preguntas si/no, menú, lista, calendario, barra de progreso, diálogo de contraseña, cuadro de texto, cuadro de mensaje, etc. Recomendamos leer la documentación del manual (man dialog) o ejecutar

dialog --help

Aparte del programa "dialog", que produce una salida por consola, puede ser que tenga en su sistema un programa "gdialog", Xdialog o "dldialog" (dependiendo del Linux que utilice), que son lo mismo, solo que abren una ventana gráfica, por X11, para el diálogo.

Sintaxis:

dialog  { --opciones específicas }

Ejemplo 1 (Diálogo "yesno"):

[jose@xtech experto]$ dialog --yesno "Desea salir?" 6 30

Produce esto:

Los argumentos 6 y 30 corresponden a la altura y ancho, respectivamente, del cuadro. En su versión X11, sería:

[jose@xtech experto]$ gdialog --yesno "Desea salir?"

Y se vería así:

Ejemplo 2 (Diálogo "inputbox"):

[jose@xtech experto]$ dialog --inputbox "Ingrese su nombre" 9 30 Juan

Note que agregamos el argumento "Juan", que será el valor predeterminado para este inputbox:

O también:

[jose@xtech experto]$ gdialog --inputbox "Ingrese su nombre"

Produce esto:

El caso del "inputbox" suele tener aparejado la necesidad de asignar ese valor ingresado a una variable. Para hacer eso tendremos que usar la siguiente sintáxis:

VARIABLE=`gdialog --inputbox "Ingrese su nombre" 2>&1`

Note que pusimos todo el comando entre comillas invertidas para que reemplace el mismo por el valor que el comando representa después de ejecutarse.

El 2>&1 es un truco que permite redirigir la STDERR hacia la STDOUT, ya que el valor ingresado sale por la salida de error en vez de la estándar.

Ejemplo 3 (Diálogo "msgbox"):

[jose@xtech experto]$ dialog --msgbox "Esto es muy bueno para mensajes" 5 50

Produce esto:

O también:

[jose@xtech experto]$ gdialog --msgbox "Esto es muy bueno para mostrar mensajes
largos o de advertencia"

Produce esto:

Ejercicio 1

Descompresión Automática de Archivos


Se debe ingresar el nombre de un archivo por la línea de comandos, y el script debe reconocer con qué herramienta está comprimida y proceder a descomprimirlo. Si el archivo no está comprimido, el script deberá devolver un mensaje de error.

TIP: utilizar el programa "file"

Resolución
#!/bin/bash
#
# Decompresor inteligente

if [ -z $1 ]
then
#
# Si no hay argumento salimos del script con error "1!
#
echo "Debe ingresar el nombre del archivo"
exit 1
else
ARCHIVO=$1
fi

TIPO=`file $ARCHIVO`
#
# Verificamos el tipo de archivo
# Salida del comando file:
#
# Para GZIP
# file ejemplo.gz
# ejemplo.gz: gzip compressed data, was "ejemplo",from Unix
#
# Para BZIP2
# file ejemplo.bz2
# ejemplo.bz2: bzip2 compressed data, block size =900k


case $TIPO in
"${ARCHIVO}: bzip2"*)
bunzip2 $ARCHIVO
;;
"${ARCHIVO}: gzip"*)
gunzip $ARCHIVO
;;
*)
echo "No esta comprimido"
;;
esac


exit 0

Ejercicio 2

Listado del Directorio Home


Se debe realizar un listado recursivo del directorio personal, y guardar la información en un archivo. Luego debe comprimirse ese archivo y preguntar al usuario en qué directorio quiere guardar el archivo comprimido.

Resolución
#/bin/bash
# Listado del Home

# Iniciamos la variable.
rm -rf ./listado.txt
touch ./listado.txt
ARCHIVO="./listado.txt"

# Listamos los archivos y los guardamos en el archivo
ls -1 ~ >> $ARCHIVO
cat $ARCHIVO

# Comprimimos el archivo como tar.gz
tar -czvf listado.tar.gz $ARCHIVO
COMPRIMIDO=listado.tar.gz

# Preguntamos al usuario donde desea guardar ese archivo.
echo "Por favor, ingrese el PATH donde desea almacenar $COMPRIMIDO."
read PATH
echo $PATH
echo $COMPRIMIDO

# Guardamos el archivo donde se indico.
mv $COMPRIMIDO $PATH

# Se imprime donde se guardo el archivo.
echo "Se guardo $COMPRIMIDO en $PATH"

exit 0

Ejercicio 3

Ralización de un backup diario


Se debe archivar como "tarball" (archivo .tar.gz) todos los archivos del directorio personal. Esto se debe hacer grabando un CR regrabable.

Resolución 1
#!/bin/bash
#
# Se limpia la pantalla para tener una salida más prolija.

clear

# Se procede a desmontar el CD por si alguien olvidó hacerlo.

echo "*** Desmontando CDROM ***"
umount /mnt/cdrom

# Se limpia nuevamente la pantalla.

clear

# Se anuncia al usuario que se comienza a borrar el CD.

echo "*** Borrando CDROM ***"
echo "Por favor, sea paciente. Este proceso puede demorar hasta 20 minutos."
echo " "

# Se utiliza el programa cdrecord para borrar el CD.

cdrecord -v -dev=ATAPI:0,0,0 -blank=fast > /dev/null

# Se borra nuevamente la pantalla.

clear

# Se anuncia por pantalla el comienzo del backup del directorio.

echo "*** Comenzando el backup ***"

# Se crea un directorio temporal para almacenar el backup.

mkdir /tmp/backup02

# Se limpia la pantalla.

clear

# Se anuncia por pantalla que se comienza a salvar el directorio personal.

echo "*** Backup del directorio Personal ***"

# Se comprime el directorio personal.

tar -cvzf /tmp/backuo02/home.tar.gz ~/ > /dev/null

# Se limpia la pantalla.

clear

# Se anuncia por pantalla que se realiza el ISO a grabar.

echo "*** Creando archivo de Resguardo ***"

# Se crea la imágen ISO.

mkisofs -r -J -o backup02.iso backup02/ > /dev/null

# Se borra la pantalla.

clear

# Se anuncia el comiezo de la grabación del CD.

echo "*** Comenzando la grabacion del CDROM ***"
echo "Por favor, sea paciente. Este proceso puede tardar hasta 30 minutos."
echo " "

# Se comienza a grabar el CD con cdrecord.

cdrecord -v speed=4 dev=ATAPI:0,0,0 -data backup02.iso > /dev/null

# Se anuncia en pantalla el borrado de los archivos auxiliares.

echo "*** Limpiando archivos extras ***"
rm -Rf /tmp/backup02.iso > /dev/null
rm -Rf /tmp/backup02 > /dev/null

# Se desmonta el CD.

umount /mnt/cdrom

# Se limpia la pantalla.

clear

# Se anuncia que el proceso finalizó con éxito.

echo "*** Se realizo el backup con exito ***"

exit 0
Resolución 2 (backup por SAMBA)
#!/bin/bash
#
# Se limpia la pantalla para tener una salida más prolija.

clear

# Se procede a desmontar el CD por si alguien olvidó hacerlo.

echo "*** Desmontando CDROM ***"
umount /mnt/cdrom

# Se limpia nuevamente la pantalla.

clear

# Se monta por red el CD de un cliente windows.

smbmount //pc3/d /mnt/cdrom -o username=usuario,password=contraseña

# Se borra nuevamente la pantalla.

clear

# Se anuncia por pantalla el comienzo del backup del directorio.

echo "*** Backup del directorio Personal ***"

# Se comprime el directorio personal.

tar -cvzf /mnt/cdrom/home.tar.gz ~/ > /dev/null

# Se desmonta el CD.

umount /mnt/cdrom

# Se limpia la pantalla.

clear

# Se anuncia que el proceso finalizó con éxito.

echo "*** Se realizo el backup con exito ***"

exit 0

3 comentarios:

gorylong said...

muy buen post, me ha ayudado mucho, aun tengo algunas dudas, pero con el material que pusistes me sirvio

Braian said...

Por nada gorylong. Saludos!

luis said...

Buen post! Creo que me va ser de utilidad :D. Saludos