SlideShare una empresa de Scribd logo
Tutorial Shell Scripts
El día a día de un administrador de Sistemas, ya sea de una importantísima red o de un modesto servidor, esta lleno de tareas repetitivas y
generalmente tediosas. Para facilitar nuestra tarea existen los scripts. Pequeños programas cuya finalidad es precisamente automatizar y
encadenar tareas relacionadas con los sistemas.
El objetivo de este tutorial es acercarnos a la programación de scripts en LINUX (UNIX) de una manera sencilla,.. Primero con nociones de teoría
y segundo con algunos ejemplos. Los ejemplos pretenden ser útiles no solo por que ayuden al lector a entender lo expuesto en la teoría sino
porque son scripts sacados de un entorno de producción real que pueden ser usados por cualquier administrador de sistemas que tenga
escenarios y necesidades parecidas.También se incluye al principio una pequeña explicación sobre los scripts en un entorno Windows.
El tutorial se divide en los siguientes puntos:
1. Introducción (Tutorial Shell Scripts I)
2. Shell en Windows
3. SCRIPTS EN LINUX: Shell de LINUX. Historia y Conceptos básicos
4. SCRIPTS EN LINUX: Estructuras de control (Tutorial Shell Scripts II)
5. SCRIPTS EN LINUX: Ejemplos de Scripts I
- Script par realizar un "ping" a todas las máquinas de nuestro sistema
6. SCRIPTS EN LINUX: Un paso adelante : SSH sin contraseña, RSYNC y AWK. (Tutorial Shell Scripts III)
7. SCRIPTS EN LINUX: Ejemplos de Scripts II.
- Script para automatizar la réplica de una Base de Datos MySQL
- Script para la creación de usuarios en varias máquinas remotas
En esta primera entrega veremos los tres primeros.
1. Introducción
Antes de empezar a meternos de lleno en el mundo de la programación de Shell-Script, haremos una pequeña introducción, explicando los
conceptos mas sencillos y realizando un breve resumen acerca de la historia de las shells, los diferentes tipos... También ex plicaremos el Crontab
para la automatización de tareas, ¿estas preparado?...pues comenzamos..
1.1 ¿Qué es una shell?
Shell es el intérprete de comandos, es decir, como los ordenadores no entienden nuestro lenguaje (sólo saben de ceros y unos), nece sitaremos
un programa intermedio, capaz de hacer que cuando nosotros tecleemos alguna orden, nuestro ordenador sea capaz de entenderlo. Es decir
proporciona comunicación directa entre el usuario y el sistema operativo.
1.2 ¿Qué es un Shell Script?
Normalmente, usamos el término Shell Script para referirnos a programas escritos para la shell de UNIX/LINUX, mientras que cuando usamos
la línea de comandos de MS-DOS ( COMMAND.COM) o el cmd.exe de Windows, nos referimos como Batch files (archivos por lotes) y los
guardaremos con extensión .bat.
La programación en shell-script es muy útil para resolver tareas repetitivas, típicas de los Administradores. Son ficheros de texto que contienen
comandos y son directamente ejecutables por el sistema.
2. Shell en Windows
La shell de comandos de los sistemas operativos Windows utiliza el intérprete de comandos Cmd.exe, que carga aplicaciones y dirige el flujo de
información entre ellas. Entra en Inicio/ejecutar y escribe cmd para iniciar una nueva instancia del intérprete de comandos.
Puedes utilizar el shell para automatizar tareas rutinarias, tales como las copias de seguridad o la administración de los pe rfiles de usuarios.
Siempre se ha he tenido la idea de que la shell de Windows es bastante limitada en comparación con UNIX ( la ausencia de comandos como grep
o awk...) Nosotros veremos un sencillo ejemplo para Windows, pero nos centraremos a lo largo del tutorial en la programación de Shell Scripts
en UNIX/LINUX.
Para comenzar, podemos probar a escribir el comando, color 57, para cambiar el color del símbolo del sistema al color blanco y el fondo a
púrpura. Una vez que hemos probado que la shell, "nos hace caso", podemos probar el resto de comandos ejecutables en la shell de Windows.
A continuación muestro en una tabla los principales comandos:
COMANDO DESCRIPCION
:ETIQ Identifica una posición de salto
%NUM Introduce parámetros en el fichero
CALL Llama a otro fichero Batch
CLS Borra la pantalla
ECHO Visualiza en pantalla una secuencia de caracteres
FOR Repite un número determinado de veces un mismo proceso
GOTO Salta y ejecuta una nueva línea indicada por una etiqueta
IF Se utiliza para saltos condicionales
PAUSE Detiene momentáneamente la ejecución de un fichero
REM Introduce un comentario
SHIFT ;@ Evita que una línea aparezca por pantalla
2.1 Argumentos
Si preparamos un script para windows o unix podemos hacerlo de tal manera que sea capaz de ejecutarse recibiendo argumentos e n el momento
de su llamada. Por ejemplo podemos crear un script de copia de seguridad que reciba como parámetros la carpeta origen y la carpeta destino.
Los argumentos que recibe un batch, son recibidos de la siguiente forma:
nombre_script argumento1 argumento2 argumento3
siendo:
%0 = nombre del archivo
%1 = argumento1
%2 = argumento2
%3 = argumento3
Podemos borrar el contenido de un parámetro con el comando SHIFT.
2.2 Variables de entorno
Para ver todas las variables de entorno registradas en tu sistema teclea set en tu consola.
El resultado puede ser parecido al siguiente:
Microsoft Windows XP [Versión 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:Documents and Settingsjavi>set
ALLUSERSPROFILE=C:Documents and SettingsAll Users.WINDOWS
APPDATA=C:Documents and SettingsjaviDatos de programa
CLASSPATH=.;C:Archivos de programaJavaj2re1.4.2libextQTJava.zip
CommonProgramFiles=C:Archivos de programaArchivos comunes
COMPUTERNAME=-JAVI-PORTATIL
ComSpec=C:WINDOWSsystem32cmd.exe
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
HOMEPATH=Documents and Settingsjavi
LOGONSERVER=JAVI-PORTATIL
NUMBER_OF_PROCESSORS=1
OS=Windows_NT
Path=C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:Arc
hivos de prog
ramaQuickTimeQTSystem;C:Archivos de programaArchivos
comunesAdobeAGL
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 9 Stepping 5, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0905
ProgramFiles=C:Archivos de programa
PROMPT=$P$G
QTJAVA=C:Archivos de programaJavaj2re1.4.2libextQTJava.zip
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:WINDOWS
TEMP=C:DOCUME~1javiCONFIG~1Temp
TMP=C:DOCUME~1javiCONFIG~1Temp
USERDOMAIN=JAVI-PORTATIL
USERNAME=javi
USERPROFILE=C:Documents and Settingsjavi
windir=C:WINDOWS
Por ejemplo, la variable COMSPEC nos indica la ubicación del interprete de comandos DOS, que suele ser command.com
(C:WINDOWSsystem32cmd.exe).
En PATH se guardan las rutas donde DOS debe buscar comandos o programas a ejecutar y en PROMPT es el símbolo de sistema que indica al
usuario que puede introducir texto. En nuestro caso se muestra la ruta donde se encuentra y el signo de mayor que.
2.3 Ejemplo
Para empezar haremos un script muy muy sencillo. Pongámonos en la situación de que somos administradores y queremos que se ha ga una
copia de seguridad de ciertas carpeta. Pues esta tarea es tan sencilla como crear un archivo ejemplo.bat con el siguiente contenido.
;@echo off REM Ejemplo1
XCOPY %SystemDrive%carpetaOrigen D:copiaSeguridad /E /I
exit
Notas
- Si lo que quisieramos copiar fuera un archivo, en vez de usar XCOPY usaríamos COPY.
- La variable de entorno SystemDrive, nos devuelve la letra del disco duro. No sería necesario usar esta variable si conocemos la ruta, pero he
considerado didáctico introducirlo en este ejemplo.
- La opción /E es para especificar que deseo copiar directorios y subdirectorios, incluyendo los que estan vacíos.
- La opción /I es para especificar que queremos crear un subdirectorio si no existe, ya que si no lo pones, nos preguntaría.
- Para mas información acerca de las opciones , teclear XCOPY /?.
2.4 Tareas programadas
Ahora si queremos que este proceso se repita cada cierto tiempo, tenemos que entender el funcionamiento del comando at, que utiliza la
siguiente sintaxis:
at
ombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,...
comando
Tendríamos que seguir los siguientes pasos para crear nuestra tarea programada:
1. Ir a Inicio/Ejecutar y escriba cmd. En la consola que se abre, escriba net start, para ver el listado con los servicios que se estan
ejecutando actualmente.
2. Si el Programador de tareas no aparece en nuestra lista, tecleé net start "task scheduler".
3. En el símbolo del sistema, escriba:
at
ombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,... comando
y, a continuación, presione ENTRAR
Por ejemplo, si quisiesemos que se ejecutase en nuestro equipo a una hora:
C:Documents and Settingspepito>at 11:20 c:/ejemplo.bat
Se ha agregado un nuevo trabajo con identificador = 1
Si queremos ver las tareas pendientes:
C:Documents and Settingspepito>at
Estado ID Día Hora Línea de comando
-----------------------------------------------------------------------
1 Hoy 11:20 c:/ejemplo.bat
Si quisieramos eliminar esa tarea:
at
ombreDeEquipo id /delete | /delete/yes
En nuestro caso, si tenemos nuestra tarea con el identificador 1.
at 1 /delete
Para mas información sobre el comando at, visitar http://support.microsoft.com/kb/313565/es
También podemos visitar esta extensa colección de ejemplos.
3. Shell de LINUX. Historia y Conceptos básicos
La Shell permite al usuario interactuar con el Kernel a través de la interpretación de los comandos que el usuario ingresa en la línea de comandos
( ó a través de los "scripts", archivos que ejecutan un conjunto de comandos).
Si quieres saber qué Shells tienes instalados en tu distribución GNU/Linux sólo tienes que teclear el comando:
cat /etc/shells ó cat /etc/shell (dependiendo de la distribución que
tengas instalada).
En mi caso, la salida de este comando es la siguiente:
# /etc/shells: valid login shells
/bin/ash
/bin/bash
/bin/csh
/bin/sh
/usr/bin/es
/usr/bin/ksh
/bin/ksh
/usr/bin/rc
/usr/bin/tcsh
/bin/tcsh
/usr/bin/zsh
/bin/sash
/bin/zsh
/usr/bin/esh
/bin/rbash
/usr/bin/screen
Para saber que tipo de Shell estamos usando, tecleamos el siguiente comando en una consola de Linux:
root@ubuntu:~# echo $SHELL
/bin/bash
Para cambiar el tipo de Shell que se esta usando usaremo el comando:
root@ubuntu:~# chsh
Es importante también saber que un script puede ejecutarse en primer o en segundo plano:
o Primer plano (foreground): se lanza introduciendo el nombre del script, pero hasta que el script no termine no se
devolverá el control de la shell al usuario.
o Segundo plano (background):se lanza igual pero añadiendo a continuación &. El control de la shell pasa
inmediatamente al usuario( normalmente usado para procesos de larga duración)
3.1 Historia de las Shells
La primera Shell fue programada por Steven Bourne (llamada por este motivo Bourne-Shell). Según las versiones se le llama sh o bsh. Es una
shell muy limitada, y usa una sintáxis de comandos usada en los primeros sistemas UNIX.
Cronológicamente, la siguiente shell fue la c-shell o csh, desarrollada por el unix BSD de Berkeley. Y cómo su nombre indica, usa comandos muy
parecidos al lenguaje de programación C. También existe una shell llamada tcsh, que es una especie de c-shell mejorada, siendo capaz de
chequear ficheros, completar nombres de variables, aliases. No suele venir incluida en las instalaciones estándar.
En 1986, David Korn en los laboratorios AT&T programó la korn- shell (ksh) que nació de juntar lo mejor de la bourne shell y la c-shell.
En la mayoría de los sistemas Linux, viene por defecto la shell bash (Bourne-Again-shell, en referencia al inventor de la primera Shell). Esta
Shell posee toda la funcionalidad del sh con características avanzadas de C Shell, por eso cualquier script escrito para una shell sh correrá
perfectamente. La shell bash fué programada por desarrolladores del proyecto GNU. La ventaja principal es su potencia y que es gratuita. Por
este motivo nosotros usaremos esta shell .
3.2 Conceptos Básicos
Para comenzar a introducirnos en el mundo de los scripts, recomendamos antes la lectura de estos artículos:
 Editor VI , ya que necesitaremos manejarnos con este editor para escribir nuestros scripts...
 La estructura del sistema de archivos en Linux , imprescindible si no se conoce el sistema de archivos de Linux.
 Introducción a la Shell de Linux, dónde se hace un breve repaso a los comandos más básicos de Linux
Antes de comenzar con ejemplos de Scripts, vamos a explicar una serie de conceptos, necesarios a la hora de implementar nuestros shell-
scripts:
3.2.1 Variables
Para asignar un valor a una variable:
valor=7
Para visualizar el contenido de la variable
root@ubuntu:~# echo $valor
7
Para borrar el contenido
root@ubuntu:~# unset valor
root@ubuntu:~# echo $valor
A continuación se muestra una tabla con una serie de variables especiales que nos serán de utilidad a la hora de escribir nue stros scripts:
VARIABLE DESCRIPCION
$0 Nombre del Shell-Script que se está ejecutando.
$n Parámetro o argumento pasado al Shell-Script en la posición n, n=1,2,...
$PS1 Prompt
$# Número de argumentos.
$* Lista de todos los argumentos.
$? Salida del último proceso ejecutado.
$$ Número de identificación del proceso (PID)
$! Número del último proceso invocado por la shell
3.2.2 Variables de entorno
Existen dos áreas de memoria en las shells para almacenar variables, el Área local de datos y el Entorno. Podemos visualizar su contenido de
ambas áreas, al igual que Windows, con el comando set.
Por defecto, cuando asignamos un valor a una variable, es local, es decir, es conocida por esa shell, pero si se abre otra shell a partir de la que
estamos, estas nuevas 'subshells' desconocen el valor de las variables que hemos asignado anteriormente.
En cambio, las variables del entorno están disponibles para las subshells. Es decir los valores de estas variables son conocidos por los procesos
hijos de la shell.
Para hacer que una variable se almacene en el área de Entorno, se utiliza el siguiente comando:
root@ubuntu:~# export nombre=javi
Para ver la lista de variables del entorno usaremos el comando env.
Debemos saber que una variable exportada NO es lo mismo que una variable global, sino una copia, ya que podrá ser modificada pero volverá a
tener su anterior valor cuando salga de la subshell.
Cómo ya sabemos, existe un conjunto de variables de entorno predefinidas, que a continuación listamos en esta tabla:
COMANDO DESCRIPCION
PATH Camino de búsqueda de órdenes
HOME Directorio de trabajo del usuario
USER Usuario que establecióla sesión
PWD Ruta completa del directorio de trabajo actual
LOGNAME Nombre del usuario que ejecuta la shell
TERM Tipo de terminal.
SHELL Shell que está ejecutándose
PS1, PS2, PS3, PS4 Prompts
3.2.3 Entrecomillado
Debido a que la shell bash puede usar nombres simbólicos que representan valores, como el path del directorio personal, necesitaremos conocer
la diferencia entre los distintos tipos de entrecomillado, el simple, el doble y el uso de las sencuencias de escape ().
Entrecomillado simple
Nos sirve para hacer que la shell tome lo encerrado entre él como una expresión literal, ya sean variables, comodines u otras expresiones
entrecomilladas.
Es decir el contenido no es interpretado por la shell.
Para entenderlo mejor, imaginemos que deseamos crear una carpeta de nombre * (asterisco).
Si lo intentamos, es decir si tecleamos mkdir *, nos dará error. Sin embargo si escribimos mkdir '*', el intérprete de comandos tomará el
carácter comodín (*) como un literal y no como un comodín, y podremos crear la carpeta con ese nombre.
Entrecomillado doble
Permiten la sustitución de parámetros, la sustitución de comandos y la evaluación de expresiones aritméticas, pero ignoran lo s caracteres
tubería, sustituciones de tilde, expansión de caracteres comodines, aliases y la división de palabras vía delimitadores.
Las comillas simples dentro de las comillas dobles no tienen efecto. Se puede incluir comillas dobles dentro de una cadena con comillas dobles
anteponiendo .
Es decir, se produce sustitución de variable (el signo del dolar se interpreta) por ejemplo, podremos ejecutar ls "$BASH" y nos devolverá
correctamente el tipo de shell (/bin/bash), pero si hacemos ls "*", el comodin será tomado como un literal.
Sencuencias de escape ()
Una barra inclinada inversa no entrecomillada, es decir , preserva el valor literal del siguiente carácter que lo acompaña.
Para entenderlo mejor, veamos un ejemplo:
root@ubuntu:~# echo $BASH
/bin/bash
Si utilizamos la encuencias de escape:
root@ubuntu:~# echo $BASH
$BASH
Veamos otros ejemplos:
root@ubuntu:~# usuario=javi
root@ubuntu:~# echo $usuario
javi
root@ubuntu:~# echo "$usuario"
javi
root@ubuntu:~# echo '$usuario'
$usuario
root@ubuntu:~# echo $usuario
$usuario
root@ubuntu:~# echo "'$usuario'"
'javi'
A continuación se muestra una tabla para que fácilmente veamos la diferencia entre un tipo de entrecomillado y otro:
EXPRESIÓN VALOR
$usuario javi
"$usuario" javi
'$usuario' $usuario
$usuario $usuario
" '$usuario' " 'javi'
3.2.4 Ejecución
Existe dos formas de ejecutar los scripts:
o Anteponiendo sh, source o bien "." al nombre del script.
root@ubuntu:~# sh ejemplo.sh
esto es un ejemplo
o
root@ubuntu:~# source ejemplo.sh
esto es un ejemplo
o
root@ubuntu:~# . ejemplo.sh
esto es un ejemplo
o
o Dando permiso de ejecución y a continuación, invocándolo con su nombre anteponiendo la ruta donde se encuentra el
script :
root@ubuntu:~# chmod +x ejemplo.sh
root@ubuntu:~# ./ejemplo.sh
o Si nos encontramos en el mismo directorio que el script :
root@ubuntu:~# . ejemplo.sh
esto es un ejemplo
Sino pondremos la ruta, por ejemplo:
root@ubuntu:~# /root/ejemplos/ejemplo.sh
esto es un ejemplo
En caso de que el directorio donde se encuentra el script este en el PATH, se podr ía ejecutar introduciendo simplemente
el nombre.
3.2.5 Parámetros
Un shell-script soporta argumentos o parámetros de entrada. Desde el interior del script se referencian mediante las variables especia les $i con
i=1, 2, ..., NumeroArgumentos. Es decir, si lanzamos el siguiente script :
root@ubuntu:~# ejemploScript uno dos gato
Tendremos que el primer parámetro es uno, el segundo dos y el tercero gato, referenciándolos en el script como $1, $2 y $3 re spectivamente.
Recordemos como ya vimos anteriormente que la variable $0 hace referencia al nombre del script.
También podemos escribirlos en la shell con el comando "set":
root@ubuntu:~# set parametro1 parametro2 parametro3
root@ubuntu:~# echo $2
parametro2
Con el comando "shift", podemos desplazar, es decir borrar varias posiciones:
root@ubuntu:~# set parametro1 parametro2 parametro3
root@ubuntu:~# shift 2
root@ubuntu:~# echo $1
parametro3
Con "shift 2" hacemos que desaparezca el valor de $1 y $2, y que ahora $1 valga lo que estaba en $3.
3.2.6 Automatización de tareas con Crontab
Crontab es una herramienta cuya función es la automatización de tareas. Por ejemplo podemos apagar un equipo a una hora determinada o
realizar backups de manera automática.
Para ver qué tareas tenemos en el crontab, deberemos ejecutar:
root@ubuntu:~#crontab -l
Veamos un ejemplo que ejecutaría el comando who todos los martes a las o nce y media de la noche, guardando la salida en fichero.txt::
30 23 * * 2 /usr/bin/who >> /home/fichero.txt
El formato de las entradas de crontab es el siguiente:
[minutos] [hora] [día] [mes] [dia_de_semana] [comando]
Teniendo en cuenta que:
 Minutos: (0-59): Es el minuto exacto en el que quieres que se ejecute la tarea
 Hora: (0-23) La hora exacta en formato de 24 horas
 Día: (1-31) Valor numérico del día del mes
 Mes: (1-12) Valor numérico del mes
 Día de la semana: (0-6), siendo 1=Lunes, 2=Martes,... 6=sábado y 0=Domingo: Valor numérico del día de la semana
 Usuario: usuario que ejecuta el comando, sino se pone, se usa root por defecto
 Comando: comando a lanzar
Para especificar todos los valores posibles de una variable se utiliza el asterisco (*).
Para agregar, quitar o modificar tareas en el crontab usaremos:
root@ubuntu:~#crontab -e
que abrirá el editor (el que hayamos definido en la variable de entorno $EDITOR) y cargará el archivo crontab correspondiente al usuario que
está logueado.
Además con los siguientes comandos también podremos:
 crontab -r: elimina el fichero crontab del usuario.
 crontab -u usuario: aplica una de las opciones anteriores para un usuario determinado.
 crontab fich: instala el fichero fich como crontab del usuario.
Ahora veamos un ejemplo de cómo ejecutar nuestro script cada 20 minutos y que la salida se guarde en un log:
20 * * * * /home/script.sh >> mylog.log
es importante no olvidar poner permisos de ejecución al script (con el
comando chmod).
Continuemos con este tutorial, ahora veremos los siguientes puntos:
- SCRIPTS EN LINUX: Estructuras de control
- SCRIPTS EN LINUX: Ejemplos de Scripts I.
4. Estructuras de control
Cómo en cualquier lenguaje de programación, necesitaremos una serie de estructuras de control que permitan modificar el flujo de ejecución de
las instrucciones de nuestro script.
4.1 If
La sintaxis mas sencilla será:
if condicion
then [bloque de comandos]
[else]
[bloque de comandos]
fi
Si queremos añadir mas condiciones:
if condicion1
then [bloque de comandos si la condición1 se
cumple]
elif condicion2
then
[bloque de comandos si la condición2 se
cumple]
else
[bloque de comandos comandos si no se
cumplen ni la condición1 ni la condición2 ]
fi
Normalmente la condición será el resultado de evaluar una primitiva o de ejecutar un comando. Veamos un ejemplo:
#!/bin/bash
pin="1234"
echo "Introduzca su pin"
read -s clave
if test "$clave" = "$pin"
then
echo "Pin correcto"
echo "Acceso permitido"
else
echo "Pin incorrecto"
fi
En este sencillo ejemplo se nos pide que introduzcamos el pin (en nuestro caso lo hemos fijado a 1234), y dependiendo si lo introducimos bien o
no, nos muestra una mensaje u otro. Más adelante veremos con mas profundidad las posibilidades del comando test.
Evaluando expresiones según código de error: && y ||
Existe otra manera de evaluar condiciones mediante la utilización de los caracteres especiales && y ||, que usan los códigos de error de un
comando.
Es decir, cada comando ejecutado devuelve un valor de salida y como vimos, sacando el valor de '$?,' podíamos saber la salida del último
proceso ejecutado.
El operador '&&' ejecuta un comando, y si es correcto ejecuta el siguiente, veamos un ejemplo:
#!/bin/bash
if ls /var && ls /etc
then
echo "ok"
else
echo "error"
fi
En este caso para que salga de mensaje ok, se tendrá que haber podido listar el directorio /var y el /etc también, y sino dará error (esto puede
ser usado cuando queremos comprobar la existencia de los directorios para nuestros script):
El operador '||' ejecuta un comando y si no es correcto ejecuta el siguiente:
#!/bin/bash
if ls /var || ls /etc
then
echo "ok"
else
echo "error"
fi
En este caso saldrá el mensaje "ok" si se ha podido listar correctamente alguno de los directorios ( /var o /etc), o los dos.
Comparación de ficheros y variables con test.
Para evaluar expresiones condicionales dentro de los 'if' se usa el comando 'test'. Veamos un resumen en la siguiente tabla:
EXPRESIONES DESCRIPCION
-b fichero Cierto si fichero existe y es un dispositivo de bloques.
-c fichero Cierto si fichero existe y es un dispositivo de caracteres.
-d fichero Cierto si fichero existe y es un directorio.
-e fichero Cierto si fichero existe.
-f fichero Cierto si fichero existe y es un fichero normal.
-g fichero Cierto si fichero existe y tiene el bit de grupo activado.
-k fichero Cierto si fichero tiene el bit de sticky activado.
-L fichero Cierto si fichero existe y es un enlace simbólico.
-p fichero Cierto si fichero existe y es una tubería nombrada.
-r fichero Cierto si fichero existe y es legible.
-s fichero Cierto si fichero existe y su tamaño es mayor que cero.
-S fichero Cierto si fichero existe y es un socket.
-t [df] Cierto si df está abierto en un terminal. Si df es omitido, se toma 1 (salida estándar) por
defecto.
-u fichero Cierto si fichero existe y tiene el bit de usuario activo.
-w fichero Cierto si fichero existe y es escribible.
-x fichero Cierto si fichero existe y es ejecutable.
-O fichero Cierto si fichero existe y es propiedad del identificador efectivo del usuario.
-G fichero Cierto si fichero existe y es propiedad del identificador efectivo del grupo.
fichero1 -nt
fichero2
Cierto si fichero1 es más reciente (en base a la fecha de modificación) que fichero2.
fichero1 -ot
fichero2
Cierto si fichero1 es más antiguo que fichero2.
fichero1 -ef
fichero2
Cierto si fichero1 y fichero2 tienen el mismo número de dispositivo y de nodo-i.
-z cadena Cierto si la longitud de cadena es cero.
-n cadena Cierto si la longitud de cadena no es cero.
cadena Cierto si la longitud de cadena no es cero.
cadena1 =
cadena2
Cierto si las cadenas son iguales.
cadena1 !=
cadena2
Cierto si las cadenas no son iguales.
! expr Cierto si expr es falsa.
expr1 -a expr2 Cierto si expr1 y expr2 son ciertas.
expr1 -o expr2 Cierto si expr1 o expr2 son ciertas.
arg1 OP arg2 OP es uno de los siguientes valores: -eq, -ne, -lt, -le, -gt, o -ge. Estos operadores
binarios aritméticos devuelven cierto si arg1 es igual, distinto, menor que, menor o igual
que, mayor que, o mayor o igual que arg2, respectivamente. arg1 y arg2 pueden ser
enteros positivos, enteros negativos, o la expresión especial -l cadena, la cual significa la
longitud de cadena.e
Veamos un ejemplo:
#!/bin/bash
echo "dame primer número"
read primero
echo "dame segundo número"
read segundo
if test $primero -lt $segundo
then
echo $primero es menor que $segundo
else
if test $primero -gt $segundo
then
echo $primero es mayor que $segundo
else
echo $primero es igual que $segundo
fi
fi
4.2 For
El bucle 'for' es una estructura de control iterativa que permite repetir una sección del programa, un número fijo de veces. Su estructura es así:
for variable in [lista de palabras]
do
comandos
done
Otra manera de escribir nuestro bucle 'for' podría ser así:
for variable in [lista de palabras]; do comandos; done
Veamos un ejemplo, en el que nos ayudamos de la ejecución del comando seq para cargar la variable:
#!/bin/bash
for variable in `seq 1 100`
do
echo $variable
done
Conseguiremos como salida un listado de los 100 primeros números.
4.3 While
Sirve para repetir un bucle mientras se cumpla la condición:
While condición
do
comandos
done
Veamos en siguiente ejemplo donde creamos una sucesión de números desde un origen, en este caso el 33, hasta el final que marca la condición
(el 100):
#!/bin/bash
num=33
while [ $num -le 100 ]
do
echo "numero: $num"
num=`expr $num + 1`
done
4.4 Until
Igual que While pero el bucle se ejecuta mientras la condición sea falsa:
Until condición
do
comandos
done
A continuación, el mismo ejemplo que el While, pero esta vez utilizando la estructura Until:
#!/bin/bash
num=33
until [ $num -eq 100 ]
do
echo "numero: $num"
num=`expr $num + 1`
done
4.5 Case
Veamos la estructura:
case variable in
patron1) comandos condicion1;;
patron2) comandos condicion2;;
...
patron n) comandos condicion n;;
*) comandos si no se cumplen ninguna;;
esac
En esta estructura cuando se encuentre un patron que coincida, se ejecuta la lista de comandos hasta los ';;' y se termina la ejecución de 'case'.
Veamos un ejemplo:
#!/bin/bash
case $1 in
start)
echo "Arranco el servidor"
;;
stop)
echo "Paro el servidor"
;;
restart)
$0 stop
$0 start
;;
*)
echo "Este script se arranca tecleando $0 start o $0 stop"
;;
esac
4.6 Select
A continuación se muestra la estructura:
select nombre_de_variable [in lista]
do
comandos
done
El siguiente ejemplo guarda en el fichero "ejemploselect" el resultado del comando ls, que lista los archivos del directorio actual, y permite
editarlo y salir:
#!/bin/bash
echo "Elige lo que quieres hacer "
fichero=/home/ejemploselect
ls > $fichero
select opciones in listar editar salir
do
case $opciones in
listar)
cat $fichero
;;
editar)
vi $fichero
;;
salir)
break
;;
esac
done
5. SCRIPTS EN LINUX: Ejemplos de Scripts I.
Ya esta bien de teoría, vamos a ver un par de scripts del mundo real. Uno de ellos nos servira para comprobar que nuestra red local de "miles"
de servidores está funcionando. El segundo script sirve para automatizar la creación de usuarios y servirá de punto de partida para otro algo más
complejo que veremos despues.
5.1 Script par realizar un "ping" a todas las máquinas de nuestro sistema.
Supongamos que somos administradores o responsables de una red con cierto número de servidores y queremos realizar periodicamente la tarea
de saber si están "levantados". Para ello escribiremos un script que lanzará un ping a todos nuestro servidores y nos avisará sonoramente
cuando uno de ellos no responda.
Lanzamos el "vi" y creamos el siguiente script que llamaremos ping.sh
#!/bin/sh
#### Defino una función con todas las operaciones para poder
llamarla recursivamente. Las funciones no se ejecutan hasta que
no
#### se les llama o invoca
ejecucion()
{
clear
#####limpia la pantalla
for server in `cat mis_servers.lst`
#### Realiza un cat del fichero mis_servers.lst y almacena
ciclicamente cada linea en la variable $server. Es decir realiza un
for
#### tantas veces como lineas tenga mis_servers.lst y almacena
el contenido de la linea en la variable $server. Para cada
ejecución
#### del for realiza lo que está entre el do y el done.
do
echo
echo Realizo un ping a la maquina $server
echo
ping -c 2 -A $server
### Manda dos paquetes de trafico icmp al destino almacenado
en server. Emite un pitido si no hay respuesta.
done
###Ahora dentro de la funcion voy a llamar a la propia funcion
para convertir el proceso en un bucle. Colocare una pausa para
### espere 2 minitos antes de volver a ejecutarse
sleep 120
ejecucion
}
ejecucion
#### Esta llamada externa es la que se va a ejecutar la primera
vez.
Necesitamos crear un fichero "mis_servers.lst"con las ip de nuestros servidores:
root@ubuntu:~# cat mis_servers.lst
192.168.1.37
192.168.1.1
192.168.1.89
Entonces al ejecutar nuestro script obtenemos:
Realizo un ping a la maquina 192.168.1.37
PING 192.168.1.37 (192.168.1.37): 56 data bytes
64 bytes from 192.168.1.37: icmp_seq=0 ttl=128 time=0.244 ms
64 bytes from 192.168.1.37: icmp_seq=1 ttl=128 time=0.269 ms
--- 192.168.1.37 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.244/0.257/0.269/0.013 ms
Realizo un ping a la maquina 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=255 time=0.637 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=0.629 ms
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.629/0.633/0.637/0.004 ms
Realizo un ping a la maquina 192.168.1.89
PING 192.168.1.89 (192.168.1.89): 56 data bytes
--- 192.168.1.89 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
5.2 Script para crear usuarios en local
Vamos a realizar un script que nos facilite la creación de usuarios en una máquina LINUX. Este script es muy bueno porque aunque ejecutado
localmente tampoco nos ahorra demasiado tiempo, puede usarse de base para un script que cree usuarios en máquinas remotas.
####Creamos una función que recoja los datos necesarios para la creacion
de usuarios
##################################################
########
###FUNCION QUE RECOGE LOS DATOS#####################
##################################################
########
peticion_datos()
{
#### Borramos el contenido de las variables que vamos a usar. Por
precaucion.
unset $user
unset $grupo1
unset $grupo2
unset $shell
unset $password
unset $casa
#### Vamos pidiendo los datos que necesitamos
echo Nombre de usuario:
read user
### Le proponemos al usuario el grupo "users", si no introduce ningun
grupo, se lo asignamos nosotros
echo Grupo principal:[users]
read grupo1
if [ "$grupo1" = "" ]
then
grupo1=users
fi
#### Puede no especificarse un grupo secundario
echo Grupo Secundario:
read grupo2
if [ "$grupo2" = "" ]
then
grupo22=""
else
grupo22="-g '$grupo2'"
fi
####Si no especifica una shell se le asigna /bin/bash
echo Shell:[/bin/bash]
read shell
if [ "$shell" = "" ]
then
shell=/bin/bash
fi
####Home del usuario, por defecto home/nombre_ususario
echo Home del usuario: [/home/$user]
read casa
if [ "$casa" = "" ]
then
casa=/home/$user
fi
####Existe el home?? Hay que crearlo???
echo Existe el home del usuario: [n]
read exist
if [ "$exist" = "" ] || [ "$exist" = "n" ]
then
param=-m
fi
#####Esta parte es la mas interesante. El comando useradd de linux permite
especificar la password del usuario, pero debemos
###### encriptarla nosotros. Le pedimos la password al usuario del script y
se la pasamos a un script de PERL. La salida
###### de dicho script la almacenamos en una variable.
echo Password:
read password
contrasena=`perl /root/scripts/crypt.pl $password`
#### El siguiente codigo es solo de control, para que muestre por pantalla el
resultado de la encriptacion.
echo ________________________
echo ----- DEBUG-------------
echo ________________________
echo $contrasena
}
##################################################
#######################
### FIN DE LA FUNCION
###############################################
##################################################
########################
###### Como ya hemos especificado antes, las funciones no se ejecutan
hasta que no se las llama.
peticion_datos
####Ejecutamos el comando de creacion de usuario
/usr/sbin/useradd -G $grupo1 $grupo22 -d $casa $param -p $contrasena
$user
El script de perl es muy sencillo. Debemos crearl el fichero crypt.pl en la misma ubicación del script de creación de usuarios. El contenido del
fichero debe ser:
#!/usr/local/bin/perl
#
# call it like so: perl crypt.pl password
srand (time());
my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65
: 97))";
my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
my $plaintext = shift;
my $crypttext = crypt ($plaintext, $salt);
print "${crypttext}";
Podemos comprobar que funciona haciendo:
root@ubuntu:~/scripts# perl crypt.pl funciona???
fFvYQ9cG.e.as
Lo que nos devuelve es la cadena encriptada equivalente a "funciona???".
Una vez que ya tenemos esto podemos probar la ejecución del script. Lo lanzamos y tenemos lo siguiente:
Nombre de usuario:
javi
Grupo principal:[users]
Grupo Secundario:
Shell:[/bin/bash]
Home del usuario: [/home/javi]
Existe el home del usuario: [n]
Password:
javierete
________________________
----- DEBUG-------------
________________________
ou47ezbisMOic
Es muy comodo porque hemos incluido opciones por defecto lo que nos permite responder a casi todas las preguntas pulsando ENTER. Ahora
vemos lo que ha originado el script.:
FICHERO /etc/passwd:
:::::
:::::
gdm:x:108:118:Gnome Display Manager:/var/lib/gdm:/bin/false
ubuntu:x:999:999:Live session user,,,:/home/ubuntu:/bin/bash
sshd:x:109:65534::/var/run/sshd:/usr/sbin/nologin
javi:x:1000:1001::/home/javi:/bin/sh
FICHERO /etc/shadow:
ubuntu:U6aMy0wojraho:13869:0:99999:7:::
sshd:!:13869:0:99999:7:::
javi:ou47ezbisMOic:13869:0:99999:7:::
Observamos que la ejecución ha generado entradas en dos ficheros. En el fichero /etc/passwd se almacenan los datos del usuario y en el
/etc/shadow se almacena la password. También se comprueba que se ha creado el directorio "home" del usuario:
root@ubuntu:~/scripts# cd /home
root@ubuntu:/home# ls -lrta
total 0
drwxrwxrwt 30 root root 240 2007-12-22 11:22 ..
drwxr-xr-x 21 ubuntu ubuntu 740 2007-12-22 11:32 ubuntu
drwxr-xr-x 2 javi javi 140 2007-12-22 12:17 javi
drwxr-xr-x 4 root root 100 2007-12-22 12:17 .
Tutorial Shell Scripts III
En esta última entrega veremos los siguientes puntos:
6. SCRIPTS EN LINUX: Un paso adelante : SSH sin contraseña, RSYNC y AWK.
7. SCRIPTS EN LINUX: Ejemplos de Scripts II.
7.1 Script para automatizar la réplica de una Base de Datos MySQL
7.2 Script para la creación de usuarios en varias máquinas remotas
6. SCRIPTS EN LINUX: Un paso adelante: SSH sin contraseña,
RSYNC y AWK.
Si habeis seguido el monográfico paso a paso, ya tendreis algunas nociones de teoría y habreis visto algunos ejemplos de scripts. Si ya nos
sentimos comodos y no estamos muy perdidos, entonces estamos listos para dar un paso adelante. En este artículo del monográfico vamos a
tratar, un poco por encima, tres nuevos aspectos teoricos. Vamos a ver como se puede realizar una conexión ssh entre dos equipos sin tener que
introducir la contraseña y vamos a ver en que consisten Rsync y AWK, dos herramientas de los entornos Unix que nos darán nuevas
posibilidades.
SSH sin contraseña.
No os asusteis, esto no significa que vayamos a tirar la seguridad de nuestra red por el suelo. Muy al contrario. Lo que vamo s a hacer es realizar
una conexión entre dos equipos usando ssh, como método de autenticación usaremos un sistema clave publica / clave privada. Lo dicho...
¡empezamos!.
Debemos determinar “que usuario de que máquina” se conectara a “que usuario de que otra máquina”.
Debemos estar logados como ”usuario a” en la “máquina a”. Una vez en esta situación debemos hacer:
ssh-keygen -t rsa
Este comando nos creara una serie de archivos en la carpeta .ssh del home del “usuario a”. Uno de esos ficheros se
llamará: $HOME/.ssh/id_rsa.pub
Ahora debemos logarnos en el “equipo b” como “usuario b” y hacer un ftp al “equipo a”. Cuando se nos solicite el user/password para el ftp
introducimos los del equipo a.
ftp > lcd /tmp
ftp> mget /home/usuario_a/.ssh/ id_rsa.pub
ftp> bye
Ahora ya tenemos el fichero en la carpeta /tmp del “equipo b”.
cat /tmp/id_rsa.pub >> $HOME/.ssh/authorized_keys
Con el comando anterior copiamos el contenido del fichero a un Nuevo fichero en la carpeta .ssh del usuario.
El último paso es dar los siguientes permisos:
chmod 0700 $HOME/.ssh/
chmod 0600 $HOME/.ssh/authorized_keys
Ahora que ya hemos terminado la tarea, debemos probar que todo ha ido bien.
Desde el equipo_a y como usuario_a hacemos:
ssh usuario_b@equipo_b
Esto debe permitirnos acceder sin contraseña. Debemos tener en cuenta que la primera vez que lo hagamos se nos solicitará incluir el equipo
remoto en el fichero known_hosts. Tecleamos yes y tenemos concluida la tarea.
¿Que nos permite esto? Pues muy facil, nos permite ejecutar comandos en máquinas remotas, y nos permite hacerlo en un script programado
en el tiempo, ya que no requiere que ningún administrador inserte la contraseña en la máquina remota .Un ejemplo, gracias a e sta forma de
conexión podriamos centralizar la ejecución de copias de seguridad sin tener que programar todas ellas. Programariamos un script en un servidor
que fuese lanzando las copias de seguridad en todos los demas y capturando las "salidas" de las ejecuciones en un solo log.
Veremos tambén como gracias a esta utilidad podemos adecuar el script que ya hemos visto de creación de usuarios para que sirva para crear
usuarios en máquinas remotas.
RSYNC
Es una utilidad típica de los sistemas UNIX. Lo primero que debemos hacer es saber si la tenemos instalada ya en nuestra distribución linux. Lo
más facil para saber si esta instalada es ejecutarla desde linea de comandos y ver que pasa. Si está instalado nos saldrá el típico mensaje de
créditos y opciones de uso:
javi$ rsync
rsync version 2.6.3 protocol version 28
Copyright (C) 1996-2004 by Andrew Tridgell and others
<HTTP: rsync.samba.org />
Capabilities: 64-bit files, socketpairs, hard links, symlinks, batchfiles,
inplace, IPv6, 32-bit system inums, 64-bit internal inums
rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and
you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
rsync is a file transfer program capable of efficient remote update
via a fast differencing algorithm.
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... [USER@]HOST:SRC DEST
....
.....
Pero bueno, al grano, ¿qué es Rsync? o mejor aun ¿para qué sirve?. Rsync nos va a permitir sincronizar carpetas dentro de una misma máquina
o en máquinas diferentes. Esto, que así dicho no parece muy espectacular es muy útil.
Aunque la cantidad de usos y parametros para usarlo es enorme , la manera más frecuente de usarlo es:
rsync -avz user_remoto@ip_serv_remoto:/carpeta_remota
/carpeta_local
Con el anterior comando lo que hacemos es sincronizar la carpeta del servidor remoto con nuestra carpeta local.
Estas dos operaciones las haremos usando el algoritmo que contiene rsync. Nos traeremos o llevaremos los ficheros y carpetas que no existan en
la carpeta destino, o que aún existiendo sean versiones anteriores. Imaginaos lo útil que es esto para hacer copias de seguridad. Basta con que
programemos un rsync para asegurarnos que una carpeta en un equipo tendrá siempre el mismo contenido que otra carpeta en otro equipo.
Con respecto al tema de las comunicaciones, rsync tiene una buenisima funcionalidad ya que permite que lo utilices sobre una conexión ssh
(cifrada). Para hacerlo basta con usarlo de la siguiente manera:
rsync -avz -e 'ssh -i /user/.ssh/id_rsa'
user@ip_serv_remoto:/carpeta_remota /carpeta_local/
ej: rsync -avz -e 'ssh -i /root/.ssh/id_rsa'
root@192.168.17.100:/tmp/bbdd_dump /tmp/ >>
/root/scripts/import.log
Con esta forma de usarlo, al montarlo sobre una conexión ssh, podremos efectuar la operación sin tener que introducir la contraseña del sistema
remoto (siempre que hayamos hecho una distribucion de clave pública). Esto nos permitirá usar rsync en nuestros scripts programados. En los
ejemplos siguientes hay un ejemplo muy claro del uso del rsync para, por ejemplo, automatizar copias de seguridad o respaldo de bases de
datos.
AWK
AWK es en si mismo todo un lenguaje de programación diseñado para tratar con textos. No nos adentraremos mucho en él (tiene infinitas
posibilidades). Veremos como podemos usarlo para tratar cadenas de texto en nuestros scripts.
Supongamos un caso en el que queramos obtener la fecha en el sistema de unos ficheros en un directorio. Todos sabemos que haciendo en la
shell:
# ls -lrta
obtenemos algo como:
root@ubuntu:~# ls -lrta
total 400
-rw-r--r-- 1 javi javi 580 Sep 5 2005 htaccess.txt
lrwxr-xr-x 1 root javi 54 Jan 11 2007 Enviar registro ->
/Users/javi/Library/Assistants/Send Registration.setup
drwxr-xr-x 5 javi javi 170 Jan 11 2007 Public
drwxr-xr-x 5 javi javi 170 Jan 12 2007 Sites
-rw-r--r-- 1 javi javi 3 Jan 12 2007 .CFUserTextEncoding
drwx------ 17 javi javi 578 Mar 16 2007 .aMule
-rw-r--r-- 1 javi javi 2611 Mar 22 2007 configuration.php
-rw-r--r-- 1 javi javi 14451 Mar 30 2007 template_css.css
drwxr-xr-x 3 javi javi 102 Apr 1 2007 PoisonDownloads
-rw-r--r-- 1 javi javi 9455 Apr 3 2007 upload.gallery.php
-rw-r--r-- 1 javi javi 3885 Apr 3 2007 show.gallery.html.php
-rw-r--r-- 1 javi javi 3332 Apr 3 2007 authEA.php
drwxr-xr-x 3 javi javi 102 Apr 20 2007 Shared
Si sobre la salida del comando invocamos awk, podemos hacer algo como:
root@ubuntu:~# ls -lrta |awk '{print ($6)}'
Sep
Jan
Jan
Jan
Jan
Mar
Mar
Mar
Apr
Apr
Apr
Apr
Apr
Es decir, le estamos diciendo que, sobre la salida del primer comando , imprima solo la 6ª columna. Podemos imprimir varias columnas
haciendo:
root@ubuntu:~# ls -lrta |awk '{print ($6 $7)}'
Sep5
Jan11
Jan11
Jan12
Jan12
Mar16
Mar22
Mar30
Apr1
Tambien podemos agregar "literales":
root@ubuntu:~# ls -lrta |awk '{print ("mes="$6" dia=" $7)}'
mes= dia=
mes=Sep dia=5
mes=Jan dia=11
mes=Jan dia=11
mes=Jan dia=12
mes=Jan dia=12
mes=Mar dia=16
mes=Mar dia=22
mes=Mar dia=30
mes=Apr dia=1
Si queremos tratar un fichero con información tabulada, en el que sabemos que en lugar del "espacio" se ha usado un separador como "|" ó ":" ó
"," podemos especificarlo. Supongamos el siguiente fichero:
root@ubuntu:~# cat fich_separadores
javier:martinez:7-8-1979:Sevilla
cristina:cacho:31-3-1979:Madrid
luis:lopez:2-2-1982:barcelona
Podemos generar una salida con el nombre y la ciudad de nacimiento sin más que indicarle al awk que el separador de campos e s el caracter ":"
:
root@ubuntu:~# cat fich_separadores |awk -F":" '{print ($1 " "
$4)}'
javier Sevilla
cristina Madrid
luis barcelona
Veremos un ejemplo de un uso útil del AWK en uno de los scripts que vienen a continuación.
7. SCRIPTS EN LINUX: Ejemplos de Scripts II.
Ahora vemos dos scripts interesantes que incluyen la última tería vista. Considero que son muy útiles y que pueden haceros la vida más fácil si
los adaptais a vuestras necesidades. ¡Vamos alla!.
7.1 Script para automatizar la réplica de una Base de Datos MySQL
Supongamos un escenario en el que tenemos dos servidores distintos. Uno de ellos tiene una aplicación con su correspondiente base de datos
(puede ser una página web...). El otro servidor lo tenemos como servidor de emergencia. es decir, tenemos una copia de la aplicación y la Base
de Datos, listo para ocupar el puesto del otro si se rompe o si hay que someterle a mantenimiento.
Si la aplicación sufre pocas modificaciones o pocos "despliegues" nuevos, no será dificil abordar la tarea de realizar las modificaciones en los dos
servidores cada vez. Sin embargo la Base de datos tendra muchas inserciones y modificaciones cada día. Con el siguiente script podremos
automatizar la tarea de llavar parejas las dos bases de datos.
Tenemos dos servidores. El servidor A es el de producción, y el servidor B es el que queremos mantener igual que el de producción. Antes de que
este script pueda funcionar deberemos haber preparado la conexión del equipo A con el B a traves de SSH basado en clave publica / claver
privada.
SERVIDOR A. /root/scripts/export_bbdd.sh
### Almacenamos la fecha en una variable, luego la usaremos
FECHA=`date '+%d_%m_%y'`
### Nos situamos en el directorio donde guardaremos el export
de la BBDD
cd /tmp/bbdd_dump
#### Borro los export que pudiese haber almacenados
rm -Rf export_*
#### Genero el export, componiendo el nombre del fichero con la
fecha. Es decir el fichero de exportación de la BBDD tendrá la
forma "export_dd_mm_yyyy" y de esa forma siempre tendrá un
nombre distinto.
mysqldump -uroot -pcontraseña --add-drop-table nombre_bbdd >
/tmp/bbdd_dump/export_$FECHA.sql
####Controlo los posibles errores en la ejecución. Esto equivale
a preguntarle al sistema si ha ido bien la ejecución del último
comando.
if [ $? -eq 0 ]
then
echo La BBDD se ha exportado con exito. >>
/root/scripts/export.log
else
echo ERROR EN LA EXPORTACION DE LA BBDD!!! LA
SALIDA DEL COMANDO HA SIDO DISTINTA DE 0.!!! >>
/root/scripts/export.log
exit
fi
#####Escribo una marca con la fecha en el log del proceso.
echo "El export del dia $FECHA se ha realizado con exito" >>
/tmp/bbdd_dump/export.log
#### Una vez hecho el export, puedo hacer que empiece la
importación en la maquina remota.
ssh root@192.168.17.102 '/root/scripts/import_bbdd.sh'
>>/tmp/bbdd_dump/export.log
SERVIDOR B. /root/scripts/import_bbdd.sh
echo >> /root/scripts/import.log
echo
"##################################################
##############" >> /root/scripts/import.log
echo >> /root/scripts/import.log
FECHA=`date '+%d_%m_%y'`
echo FECHA DE LA EJECUCION: $FECHA >> /root/scripts/import.log
######Nos situamos en el directorio desde donde importaremos el fichero
sql que se ha generado en el anterior proceso.
cd /tmp/bbdd_dump
rm -rf *
###### Control de errores
if [ $? -eq 0 ]
then
echo El borrado del sql anterior se ha realizado con exito. >>
/root/scripts/import.log
else
echo ERROR EN EL BORRADO DE FICHEROS!!! LA SALIDA DEL
COMANDO HA SIDO DISTINTA DE 0.!!! >> /root/scripts/import.log
exit
fi
##### Aquí nos traemos los ficheros que se han generado en el primer
proceso.
rsync -avz -e 'ssh -i /root/.ssh/id_rsa'
root@192.168.17.100:/tmp/bbdd_dump /tmp/ >> /root/scripts/import.log
##### Control de errores
if [ $? -eq 0 ]
then
echo El rsync se ha realizado con exito. >> /root/scripts/import.log
else
echo ERROR EN EL RSYNC!!! LA SALIDA DEL COMANDO HA SIDO
DISTINTA DE 0.!!! >> /root/scripts/import.log
exit
fi
###### Importación en la bbdd del fichero que nos hemos traido.
mysql -uroot -pcontraseña --database nombre_bbdd <
/tmp/bbdd_dump/export*.sql >> /root/scripts/import.log
if [ $? -eq 0 ]
then
echo La importacion del sql se ha realizado con exito. >>
/root/scripts/import.log
else
echo ERROR EN LA IMPORTACION DEL SQL. LA SALIDA DEL
COMANDO HA SIDO DISTINTA DE 0. >> /root/scripts/import.log
exit
fi
En general, si usamos un script para una tarea medianamente crítica es importante redirigir la salida del mismo a un fichero de log y controlar
bien los errores generando comentarios en el log que nos permitan conocer o saber los distintos pasos " correctos" que ha ido dando nuestro
script.
7.2 Script para la creación de usuarios en varias máquinas remotas
Este script es muy parecido al que ya habiamos visto. Para poder ejecutarlo automáticamente contra máquinas remotas deberemos haber
preparado las conexiones ssh basadas en clave pública / clave privada desde el servidor que ejecuta el script a los servidores donde querem os
administrar (crear) los usuarios.
echo -------------------------------------------------------------------------------------
--
echo ------- SCRIPT PARA LA ADMINISTRACION CENTRALIZADA DE
USUARIOS ----------------------
echo -------------------------------------------------------------------------------------
--
echo
##################################################
########
###FUNCION QUE RECOGE LOS
DATOS###########################
##################################################
########
#
#
peticion_datos()
{
######## "Limpio" los posibles valores de las variables que voy a usar.
unset $user
unset $grupo1
unset $grupo2
unset $shell
unset $password
unset $casa
######### Comienzo a pedirle datos al usuario. En muchos de los campos
se le ofrecen opciones por defecto.
echo Nombre de usuario:
read user
echo Identificador de Usuario
read ID
echo Grupo principal:[users]
read grupo1
if [ "$grupo1" = "" ]
then
grupo1=users
fi
echo Grupo Secundario:
read grupo2
if [ "$grupo2" = "" ]
then
grupo22=""
else
grupo22="-g 'grupo2'"
fi
echo Shell:[/bin/bash]
read shell
if [ "$shell" = "" ]
then
shell=/bin/bash
fi
echo Home del usuario: [/home/$user]
read casa
if [ "$casa" = "" ]
then
casa=/home/$user
fi
echo Existe el home del usuario: [n]
read exist
if [ "$exist" = "" ] || [ "$exist" = "n" ]
then
param=-m
fi
######### Aquí se le pide la password. Esto ya lo habiamos visto en un
script anterior. Hace falta disponer del crypt.pl
echo Password:
read password
contrasena=`perl /root/scripts/crypt.pl $password`
########Se muestra la contraseña encriptada para comprobar que el script
de perl está funcionando correctamente.
echo ________________________
echo ----- DEBUG-------------
echo ________________________
echo $contrasena
}
##################################################
#######################
### FIN DE LA
FUNCION ############################################
###
##################################################
########################
##################################################
########################
### FUNCION QUE GENERA EL
COMANDO #########################
##################################################
########################
generar_comando()
{
comando="/usr/sbin/useradd -u $ID -G $grupo1 $grupo22 -d
$casa $param -p $contrasena $user"
}
##################################################
#######################
### FIN DE LA
FUNCION ############################################
###
##################################################
########################
echo En esta opcion podra crear un usuario en maquinas remotas. Puede
crearlo en una maquina, en una zona o en todas las maquinas.
echo Para poder ejecutarse correctamente, la maquina remota debe tener
dado de alta el usuario troya con los permisos correspondientes.
echo
echo Especifique si desea realizar la operacion contra una maquina "(1)",
contra una zona "(2)":
####Esta parte esta muy bien. Se le ofrece al usuario la opcion de ejecutar la
accion contra un ordenador
###### o contra una lista de ordenadores. Las listas son ficheros
almacenados en un directorio que en nuestro
######caso denominamos zonas.
read opcion
case $opcion in
1)
echo inserte el nombre o la ip del servidor:
read server
peticion_datos
generar_comando
ssh root@$server "$comando"
echo $comando
;;
2)
echo Las zonas definidas son:
### Accedo a al directorio de zonas y me quedo con los nombres de los
ficheros que en el se encuentran
cd zonas
echo `ls -lrta |grep "-r" |awk '{ print $9 }'`
echo
echo Seleccione la zona sobre la que actuar:
read zona
peticion_datos
for server in `cat $zona | awk -F"|" '{print $1}'`
#### Esto se interpreta: "Para cada ip almacenada en la primera columna del
fichero, usando de separador "|", haz lo que sigue."
do
echo Estoy con la maquina $server ### Para controlar en la
pantalla en que servidor andamos
generar_comando
ssh root@$server "$comando"
echo $comando
done
;;
*)
echo La opcion elegida no es correcta
echo ..........Saliendo.............
exit
;;
esac
Si se ha seguido con detenimiento el script os dareis cuenta que las llamadas "zonas"deben definirse en un fichero almacenado en una carpeta
/zonas que "cuelga" de la ubicación del script. Los ficheros de listas de servidores que se almacenan en dicha carpeta deben seguir la siguiente
estructura:
192.168.1.33|Ordenador bbdd mysql
192.168.1.43|Servidor web
192.168.1.75|Servidor de correo
Viendo la estructura del script no os será nada dificil el ir añadiendo funcionalidades tales como borrar usuarios, consultar los usuarios de un
servidor etc...

Más contenido relacionado

La actualidad más candente

Aplicar los pricipios de programacion en la solucion de problemas 33
Aplicar los pricipios de programacion en la solucion de problemas 33Aplicar los pricipios de programacion en la solucion de problemas 33
Aplicar los pricipios de programacion en la solucion de problemas 33Jahir Sanchez Sdval
 
Curso De IniciacióN Al Lenguaje C
Curso De IniciacióN Al Lenguaje CCurso De IniciacióN Al Lenguaje C
Curso De IniciacióN Al Lenguaje Cguestbc0748
 
Apuntes de c
Apuntes de cApuntes de c
Apuntes de c
Daniel Segovia
 
Comandos ms dos
Comandos ms dosComandos ms dos
Comandos ms dos
Sykrayo
 
About debuggers.help
About debuggers.helpAbout debuggers.help
About debuggers.help
tiopocho
 
Lolo
LoloLolo
Lolo
Maus Mb
 
Manual Pascal
Manual PascalManual Pascal
Manual Pascal
CEUNISAL
 
Unidad 3
Unidad 3Unidad 3
Unidad 3luz0987
 
4035426 ejercicios-resueltos-en-pascal
4035426 ejercicios-resueltos-en-pascal4035426 ejercicios-resueltos-en-pascal
4035426 ejercicios-resueltos-en-pascal
Luis Fernando Jimenez
 
Tutorial de prolog
Tutorial de prologTutorial de prolog
Tutorial de prologIvan
 
Turbo c++ 3.0
Turbo c++ 3.0Turbo c++ 3.0
Turbo c++ 3.0
Jorge Ñauñay
 

La actualidad más candente (15)

Aplicar los pricipios de programacion en la solucion de problemas 33
Aplicar los pricipios de programacion en la solucion de problemas 33Aplicar los pricipios de programacion en la solucion de problemas 33
Aplicar los pricipios de programacion en la solucion de problemas 33
 
Curso De IniciacióN Al Lenguaje C
Curso De IniciacióN Al Lenguaje CCurso De IniciacióN Al Lenguaje C
Curso De IniciacióN Al Lenguaje C
 
Tasm
TasmTasm
Tasm
 
Apuntes de c
Apuntes de cApuntes de c
Apuntes de c
 
Comandos ms dos
Comandos ms dosComandos ms dos
Comandos ms dos
 
About debuggers.help
About debuggers.helpAbout debuggers.help
About debuggers.help
 
Lolo
LoloLolo
Lolo
 
Manual Pascal
Manual PascalManual Pascal
Manual Pascal
 
UNIDAD 3
UNIDAD 3 UNIDAD 3
UNIDAD 3
 
Unidad 3
Unidad 3Unidad 3
Unidad 3
 
4035426 ejercicios-resueltos-en-pascal
4035426 ejercicios-resueltos-en-pascal4035426 ejercicios-resueltos-en-pascal
4035426 ejercicios-resueltos-en-pascal
 
Tutorial de prolog
Tutorial de prologTutorial de prolog
Tutorial de prolog
 
Turbo c++ 3.0
Turbo c++ 3.0Turbo c++ 3.0
Turbo c++ 3.0
 
Unidad 3
Unidad 3Unidad 3
Unidad 3
 
Apuntes php
Apuntes phpApuntes php
Apuntes php
 

Destacado

Linux ejemplo de comandos
Linux ejemplo de comandosLinux ejemplo de comandos
Linux ejemplo de comandosJose Barraza
 
Red HAT
Red HATRed HAT
Red hat jose miguel_suarez_villa
Red hat jose miguel_suarez_villaRed hat jose miguel_suarez_villa
Red hat jose miguel_suarez_villa
Jose Suarez
 
Comandos GNU/Linux-Unix y programación shell.
Comandos GNU/Linux-Unix y programación shell.Comandos GNU/Linux-Unix y programación shell.
Comandos GNU/Linux-Unix y programación shell.Alan Resendiz
 
Linux comandos 1
Linux comandos 1Linux comandos 1
Linux comandos 1
Manuel Antonio Arroyo Arceo
 
Manual de usuario, administracion e instalacion de servidores linux debian ...
Manual de usuario, administracion e instalacion de servidores linux   debian ...Manual de usuario, administracion e instalacion de servidores linux   debian ...
Manual de usuario, administracion e instalacion de servidores linux debian ...xavazquez
 
20 comandos linux que todos los administradores deben conocer
20 comandos linux que todos los administradores deben conocer20 comandos linux que todos los administradores deben conocer
20 comandos linux que todos los administradores deben conocer
OpenWebinars.net
 

Destacado (8)

Linux ejemplo de comandos
Linux ejemplo de comandosLinux ejemplo de comandos
Linux ejemplo de comandos
 
Curso Bash 1
Curso Bash 1Curso Bash 1
Curso Bash 1
 
Red HAT
Red HATRed HAT
Red HAT
 
Red hat jose miguel_suarez_villa
Red hat jose miguel_suarez_villaRed hat jose miguel_suarez_villa
Red hat jose miguel_suarez_villa
 
Comandos GNU/Linux-Unix y programación shell.
Comandos GNU/Linux-Unix y programación shell.Comandos GNU/Linux-Unix y programación shell.
Comandos GNU/Linux-Unix y programación shell.
 
Linux comandos 1
Linux comandos 1Linux comandos 1
Linux comandos 1
 
Manual de usuario, administracion e instalacion de servidores linux debian ...
Manual de usuario, administracion e instalacion de servidores linux   debian ...Manual de usuario, administracion e instalacion de servidores linux   debian ...
Manual de usuario, administracion e instalacion de servidores linux debian ...
 
20 comandos linux que todos los administradores deben conocer
20 comandos linux que todos los administradores deben conocer20 comandos linux que todos los administradores deben conocer
20 comandos linux que todos los administradores deben conocer
 

Similar a Tutorial shell scripts

Practica 1 unidad 4
Practica 1 unidad 4Practica 1 unidad 4
Practica 1 unidad 4
Juan Lopez
 
Funciones y caracterisricas de los sistemas operativos
Funciones y caracterisricas de los sistemas operativosFunciones y caracterisricas de los sistemas operativos
Funciones y caracterisricas de los sistemas operativosdariosirving
 
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
Ichinose 11
 
linux comando
linux comandolinux comando
tutorial0.pdf
tutorial0.pdftutorial0.pdf
tutorial0.pdf
JvAlvarado
 
Comando de linux
Comando de linuxComando de linux
Comando de linux
Ashley Stronghold Witwicky
 
Comandos linux unix de manipulación de archivos y directorios
Comandos linux unix de manipulación de archivos y directoriosComandos linux unix de manipulación de archivos y directorios
Comandos linux unix de manipulación de archivos y directorios
karlosp316
 
Comandos basicos linux
Comandos basicos linuxComandos basicos linux
Comandos basicos linuxvictdiazm
 
Shellt
ShelltShellt
Sistemas operativo g11
Sistemas operativo g11Sistemas operativo g11
Sistemas operativo g11
ELKINBARRERO1
 
Comandos
ComandosComandos
Comandos
Ivan Zamora
 
Programacinenshell linux
Programacinenshell linuxProgramacinenshell linux
Programacinenshell linuxusupr2014
 
Conceptos básicos
Conceptos básicosConceptos básicos
Conceptos básicospablo
 
Introduccion al assembler
Introduccion al assemblerIntroduccion al assembler
Introduccion al assembler
Romi Walter Miranda
 
Introduccion al assembler[1]
Introduccion al assembler[1]Introduccion al assembler[1]
Introduccion al assembler[1]
Juan Guillermo Escobar Uribe
 

Similar a Tutorial shell scripts (20)

Practica 1 unidad 4
Practica 1 unidad 4Practica 1 unidad 4
Practica 1 unidad 4
 
Funciones y caracterisricas de los sistemas operativos
Funciones y caracterisricas de los sistemas operativosFunciones y caracterisricas de los sistemas operativos
Funciones y caracterisricas de los sistemas operativos
 
17 comandos basicoslinuxasoitson
17 comandos basicoslinuxasoitson17 comandos basicoslinuxasoitson
17 comandos basicoslinuxasoitson
 
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
Laboratorio n3 sistemas_operativos_gilberto_ramos_9-748-1883
 
Curso básico linux
Curso básico linuxCurso básico linux
Curso básico linux
 
Linux
LinuxLinux
Linux
 
linux comando
linux comandolinux comando
linux comando
 
tutorial0.pdf
tutorial0.pdftutorial0.pdf
tutorial0.pdf
 
Comando de linux
Comando de linuxComando de linux
Comando de linux
 
Comandos linux unix de manipulación de archivos y directorios
Comandos linux unix de manipulación de archivos y directoriosComandos linux unix de manipulación de archivos y directorios
Comandos linux unix de manipulación de archivos y directorios
 
Comandos basicos linux
Comandos basicos linuxComandos basicos linux
Comandos basicos linux
 
Shellt
ShelltShellt
Shellt
 
Sistemas operativo g11
Sistemas operativo g11Sistemas operativo g11
Sistemas operativo g11
 
arquitectura-de-linux
arquitectura-de-linuxarquitectura-de-linux
arquitectura-de-linux
 
Comandos
ComandosComandos
Comandos
 
Programacinenshell linux
Programacinenshell linuxProgramacinenshell linux
Programacinenshell linux
 
Conceptos básicos
Conceptos básicosConceptos básicos
Conceptos básicos
 
Introduccion al assembler
Introduccion al assemblerIntroduccion al assembler
Introduccion al assembler
 
Introduccion al assembler[1]
Introduccion al assembler[1]Introduccion al assembler[1]
Introduccion al assembler[1]
 
NASM
NASM NASM
NASM
 

Más de ScreenMedia

Solucionario de dennis g zill ecuaciones diferenciales
Solucionario de dennis g zill   ecuaciones diferencialesSolucionario de dennis g zill   ecuaciones diferenciales
Solucionario de dennis g zill ecuaciones diferenciales
ScreenMedia
 
Para montar una red se necesita
Para montar una red se necesitaPara montar una red se necesita
Para montar una red se necesitaScreenMedia
 
Guia practica de debian gnu linux 2.2
Guia practica de debian gnu linux 2.2Guia practica de debian gnu linux 2.2
Guia practica de debian gnu linux 2.2
ScreenMedia
 
Sobre samba
Sobre sambaSobre samba
Sobre samba
ScreenMedia
 
Ccna4.0 protocolo vector distancia
Ccna4.0 protocolo vector distanciaCcna4.0 protocolo vector distancia
Ccna4.0 protocolo vector distancia
ScreenMedia
 

Más de ScreenMedia (6)

Solucionario de dennis g zill ecuaciones diferenciales
Solucionario de dennis g zill   ecuaciones diferencialesSolucionario de dennis g zill   ecuaciones diferenciales
Solucionario de dennis g zill ecuaciones diferenciales
 
Para montar una red se necesita
Para montar una red se necesitaPara montar una red se necesita
Para montar una red se necesita
 
Guia practica de debian gnu linux 2.2
Guia practica de debian gnu linux 2.2Guia practica de debian gnu linux 2.2
Guia practica de debian gnu linux 2.2
 
Sobre samba
Sobre sambaSobre samba
Sobre samba
 
Postfix
PostfixPostfix
Postfix
 
Ccna4.0 protocolo vector distancia
Ccna4.0 protocolo vector distanciaCcna4.0 protocolo vector distancia
Ccna4.0 protocolo vector distancia
 

Último

Desarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdfDesarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdf
samuelvideos
 
Ventajas y desventajas de la desinfección con cloro
Ventajas y desventajas de la desinfección con cloroVentajas y desventajas de la desinfección con cloro
Ventajas y desventajas de la desinfección con cloro
durangense277
 
proyecto invernadero desde el departamento de tecnología para Erasmus
proyecto invernadero desde el departamento de tecnología para Erasmusproyecto invernadero desde el departamento de tecnología para Erasmus
proyecto invernadero desde el departamento de tecnología para Erasmus
raquelariza02
 
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdfTRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
thomasdcroz38
 
Estructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdfEstructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdf
cristianrb0324
 
Inteligencia Artificial y Ciberseguridad.pdf
Inteligencia Artificial y Ciberseguridad.pdfInteligencia Artificial y Ciberseguridad.pdf
Inteligencia Artificial y Ciberseguridad.pdf
Emilio Casbas
 
Diagrama de flujo - ingenieria de sistemas 5to semestre
Diagrama de flujo - ingenieria de sistemas 5to semestreDiagrama de flujo - ingenieria de sistemas 5to semestre
Diagrama de flujo - ingenieria de sistemas 5to semestre
DiegoCampos433849
 
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
vazquezgarciajesusma
 
3Redu: Responsabilidad, Resiliencia y Respeto
3Redu: Responsabilidad, Resiliencia y Respeto3Redu: Responsabilidad, Resiliencia y Respeto
3Redu: Responsabilidad, Resiliencia y Respeto
cdraco
 
Conceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdfConceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdf
ValeriaAyala48
 
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
espinozaernesto427
 
Diagrama de flujo soporte técnico 5to semestre
Diagrama de flujo soporte técnico 5to semestreDiagrama de flujo soporte técnico 5to semestre
Diagrama de flujo soporte técnico 5to semestre
rafaelsalazar0615
 
biogas industrial para guiarse en proyectos
biogas industrial para guiarse en proyectosbiogas industrial para guiarse en proyectos
biogas industrial para guiarse en proyectos
Luis Enrique Zafra Haro
 
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTALINFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
CrystalRomero18
 
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdfDESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
sarasofiamontezuma
 
Estructuras básicas_ conceptos básicos de programación.pdf
Estructuras básicas_  conceptos básicos de programación.pdfEstructuras básicas_  conceptos básicos de programación.pdf
Estructuras básicas_ conceptos básicos de programación.pdf
ItsSofi
 
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdfDESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
marianabz2403
 
Posnarrativas en la era de la IA generativa
Posnarrativas en la era de la IA generativaPosnarrativas en la era de la IA generativa
Posnarrativas en la era de la IA generativa
Fernando Villares
 
leidy fuentes - power point -expocccion -unidad 4 (1).pptx
leidy fuentes - power point -expocccion -unidad 4 (1).pptxleidy fuentes - power point -expocccion -unidad 4 (1).pptx
leidy fuentes - power point -expocccion -unidad 4 (1).pptx
Leidyfuentes19
 
EduFlex, una educación accesible para quienes no entienden en clases
EduFlex, una educación accesible para quienes no entienden en clasesEduFlex, una educación accesible para quienes no entienden en clases
EduFlex, una educación accesible para quienes no entienden en clases
PABLOCESARGARZONBENI
 

Último (20)

Desarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdfDesarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdf
 
Ventajas y desventajas de la desinfección con cloro
Ventajas y desventajas de la desinfección con cloroVentajas y desventajas de la desinfección con cloro
Ventajas y desventajas de la desinfección con cloro
 
proyecto invernadero desde el departamento de tecnología para Erasmus
proyecto invernadero desde el departamento de tecnología para Erasmusproyecto invernadero desde el departamento de tecnología para Erasmus
proyecto invernadero desde el departamento de tecnología para Erasmus
 
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdfTRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
TRABAJO DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
 
Estructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdfEstructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdf
 
Inteligencia Artificial y Ciberseguridad.pdf
Inteligencia Artificial y Ciberseguridad.pdfInteligencia Artificial y Ciberseguridad.pdf
Inteligencia Artificial y Ciberseguridad.pdf
 
Diagrama de flujo - ingenieria de sistemas 5to semestre
Diagrama de flujo - ingenieria de sistemas 5to semestreDiagrama de flujo - ingenieria de sistemas 5to semestre
Diagrama de flujo - ingenieria de sistemas 5to semestre
 
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informática
 
3Redu: Responsabilidad, Resiliencia y Respeto
3Redu: Responsabilidad, Resiliencia y Respeto3Redu: Responsabilidad, Resiliencia y Respeto
3Redu: Responsabilidad, Resiliencia y Respeto
 
Conceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdfConceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdf
 
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...
 
Diagrama de flujo soporte técnico 5to semestre
Diagrama de flujo soporte técnico 5to semestreDiagrama de flujo soporte técnico 5to semestre
Diagrama de flujo soporte técnico 5to semestre
 
biogas industrial para guiarse en proyectos
biogas industrial para guiarse en proyectosbiogas industrial para guiarse en proyectos
biogas industrial para guiarse en proyectos
 
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTALINFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
INFORME DE LAS FICHAS.docx.pdf LICEO DEPARTAMENTAL
 
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdfDESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLLO DE HABILIDADES DE PENSAMIENTO.pdf
 
Estructuras básicas_ conceptos básicos de programación.pdf
Estructuras básicas_  conceptos básicos de programación.pdfEstructuras básicas_  conceptos básicos de programación.pdf
Estructuras básicas_ conceptos básicos de programación.pdf
 
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdfDESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
DESARROLO DE HABILIDADES DE PENSAMIENTO.pdf
 
Posnarrativas en la era de la IA generativa
Posnarrativas en la era de la IA generativaPosnarrativas en la era de la IA generativa
Posnarrativas en la era de la IA generativa
 
leidy fuentes - power point -expocccion -unidad 4 (1).pptx
leidy fuentes - power point -expocccion -unidad 4 (1).pptxleidy fuentes - power point -expocccion -unidad 4 (1).pptx
leidy fuentes - power point -expocccion -unidad 4 (1).pptx
 
EduFlex, una educación accesible para quienes no entienden en clases
EduFlex, una educación accesible para quienes no entienden en clasesEduFlex, una educación accesible para quienes no entienden en clases
EduFlex, una educación accesible para quienes no entienden en clases
 

Tutorial shell scripts

  • 1. Tutorial Shell Scripts El día a día de un administrador de Sistemas, ya sea de una importantísima red o de un modesto servidor, esta lleno de tareas repetitivas y generalmente tediosas. Para facilitar nuestra tarea existen los scripts. Pequeños programas cuya finalidad es precisamente automatizar y encadenar tareas relacionadas con los sistemas. El objetivo de este tutorial es acercarnos a la programación de scripts en LINUX (UNIX) de una manera sencilla,.. Primero con nociones de teoría y segundo con algunos ejemplos. Los ejemplos pretenden ser útiles no solo por que ayuden al lector a entender lo expuesto en la teoría sino porque son scripts sacados de un entorno de producción real que pueden ser usados por cualquier administrador de sistemas que tenga escenarios y necesidades parecidas.También se incluye al principio una pequeña explicación sobre los scripts en un entorno Windows. El tutorial se divide en los siguientes puntos: 1. Introducción (Tutorial Shell Scripts I) 2. Shell en Windows 3. SCRIPTS EN LINUX: Shell de LINUX. Historia y Conceptos básicos 4. SCRIPTS EN LINUX: Estructuras de control (Tutorial Shell Scripts II) 5. SCRIPTS EN LINUX: Ejemplos de Scripts I - Script par realizar un "ping" a todas las máquinas de nuestro sistema 6. SCRIPTS EN LINUX: Un paso adelante : SSH sin contraseña, RSYNC y AWK. (Tutorial Shell Scripts III) 7. SCRIPTS EN LINUX: Ejemplos de Scripts II. - Script para automatizar la réplica de una Base de Datos MySQL - Script para la creación de usuarios en varias máquinas remotas En esta primera entrega veremos los tres primeros. 1. Introducción Antes de empezar a meternos de lleno en el mundo de la programación de Shell-Script, haremos una pequeña introducción, explicando los conceptos mas sencillos y realizando un breve resumen acerca de la historia de las shells, los diferentes tipos... También ex plicaremos el Crontab para la automatización de tareas, ¿estas preparado?...pues comenzamos.. 1.1 ¿Qué es una shell? Shell es el intérprete de comandos, es decir, como los ordenadores no entienden nuestro lenguaje (sólo saben de ceros y unos), nece sitaremos un programa intermedio, capaz de hacer que cuando nosotros tecleemos alguna orden, nuestro ordenador sea capaz de entenderlo. Es decir proporciona comunicación directa entre el usuario y el sistema operativo. 1.2 ¿Qué es un Shell Script? Normalmente, usamos el término Shell Script para referirnos a programas escritos para la shell de UNIX/LINUX, mientras que cuando usamos la línea de comandos de MS-DOS ( COMMAND.COM) o el cmd.exe de Windows, nos referimos como Batch files (archivos por lotes) y los guardaremos con extensión .bat. La programación en shell-script es muy útil para resolver tareas repetitivas, típicas de los Administradores. Son ficheros de texto que contienen comandos y son directamente ejecutables por el sistema. 2. Shell en Windows La shell de comandos de los sistemas operativos Windows utiliza el intérprete de comandos Cmd.exe, que carga aplicaciones y dirige el flujo de información entre ellas. Entra en Inicio/ejecutar y escribe cmd para iniciar una nueva instancia del intérprete de comandos.
  • 2. Puedes utilizar el shell para automatizar tareas rutinarias, tales como las copias de seguridad o la administración de los pe rfiles de usuarios. Siempre se ha he tenido la idea de que la shell de Windows es bastante limitada en comparación con UNIX ( la ausencia de comandos como grep o awk...) Nosotros veremos un sencillo ejemplo para Windows, pero nos centraremos a lo largo del tutorial en la programación de Shell Scripts en UNIX/LINUX. Para comenzar, podemos probar a escribir el comando, color 57, para cambiar el color del símbolo del sistema al color blanco y el fondo a púrpura. Una vez que hemos probado que la shell, "nos hace caso", podemos probar el resto de comandos ejecutables en la shell de Windows. A continuación muestro en una tabla los principales comandos: COMANDO DESCRIPCION :ETIQ Identifica una posición de salto %NUM Introduce parámetros en el fichero CALL Llama a otro fichero Batch CLS Borra la pantalla ECHO Visualiza en pantalla una secuencia de caracteres FOR Repite un número determinado de veces un mismo proceso GOTO Salta y ejecuta una nueva línea indicada por una etiqueta IF Se utiliza para saltos condicionales PAUSE Detiene momentáneamente la ejecución de un fichero REM Introduce un comentario SHIFT ;@ Evita que una línea aparezca por pantalla 2.1 Argumentos Si preparamos un script para windows o unix podemos hacerlo de tal manera que sea capaz de ejecutarse recibiendo argumentos e n el momento de su llamada. Por ejemplo podemos crear un script de copia de seguridad que reciba como parámetros la carpeta origen y la carpeta destino. Los argumentos que recibe un batch, son recibidos de la siguiente forma: nombre_script argumento1 argumento2 argumento3 siendo: %0 = nombre del archivo %1 = argumento1 %2 = argumento2 %3 = argumento3 Podemos borrar el contenido de un parámetro con el comando SHIFT. 2.2 Variables de entorno Para ver todas las variables de entorno registradas en tu sistema teclea set en tu consola. El resultado puede ser parecido al siguiente:
  • 3. Microsoft Windows XP [Versión 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:Documents and Settingsjavi>set ALLUSERSPROFILE=C:Documents and SettingsAll Users.WINDOWS APPDATA=C:Documents and SettingsjaviDatos de programa CLASSPATH=.;C:Archivos de programaJavaj2re1.4.2libextQTJava.zip CommonProgramFiles=C:Archivos de programaArchivos comunes COMPUTERNAME=-JAVI-PORTATIL ComSpec=C:WINDOWSsystem32cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=Documents and Settingsjavi LOGONSERVER=JAVI-PORTATIL NUMBER_OF_PROCESSORS=1 OS=Windows_NT Path=C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:Arc hivos de prog ramaQuickTimeQTSystem;C:Archivos de programaArchivos comunesAdobeAGL PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 6 Model 9 Stepping 5, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=0905 ProgramFiles=C:Archivos de programa PROMPT=$P$G QTJAVA=C:Archivos de programaJavaj2re1.4.2libextQTJava.zip SESSIONNAME=Console SystemDrive=C: SystemRoot=C:WINDOWS TEMP=C:DOCUME~1javiCONFIG~1Temp TMP=C:DOCUME~1javiCONFIG~1Temp USERDOMAIN=JAVI-PORTATIL USERNAME=javi USERPROFILE=C:Documents and Settingsjavi windir=C:WINDOWS Por ejemplo, la variable COMSPEC nos indica la ubicación del interprete de comandos DOS, que suele ser command.com (C:WINDOWSsystem32cmd.exe). En PATH se guardan las rutas donde DOS debe buscar comandos o programas a ejecutar y en PROMPT es el símbolo de sistema que indica al usuario que puede introducir texto. En nuestro caso se muestra la ruta donde se encuentra y el signo de mayor que. 2.3 Ejemplo Para empezar haremos un script muy muy sencillo. Pongámonos en la situación de que somos administradores y queremos que se ha ga una copia de seguridad de ciertas carpeta. Pues esta tarea es tan sencilla como crear un archivo ejemplo.bat con el siguiente contenido. ;@echo off REM Ejemplo1 XCOPY %SystemDrive%carpetaOrigen D:copiaSeguridad /E /I exit
  • 4. Notas - Si lo que quisieramos copiar fuera un archivo, en vez de usar XCOPY usaríamos COPY. - La variable de entorno SystemDrive, nos devuelve la letra del disco duro. No sería necesario usar esta variable si conocemos la ruta, pero he considerado didáctico introducirlo en este ejemplo. - La opción /E es para especificar que deseo copiar directorios y subdirectorios, incluyendo los que estan vacíos. - La opción /I es para especificar que queremos crear un subdirectorio si no existe, ya que si no lo pones, nos preguntaría. - Para mas información acerca de las opciones , teclear XCOPY /?. 2.4 Tareas programadas Ahora si queremos que este proceso se repita cada cierto tiempo, tenemos que entender el funcionamiento del comando at, que utiliza la siguiente sintaxis: at ombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,... comando Tendríamos que seguir los siguientes pasos para crear nuestra tarea programada: 1. Ir a Inicio/Ejecutar y escriba cmd. En la consola que se abre, escriba net start, para ver el listado con los servicios que se estan ejecutando actualmente. 2. Si el Programador de tareas no aparece en nuestra lista, tecleé net start "task scheduler". 3. En el símbolo del sistema, escriba: at
  • 5. ombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,... comando y, a continuación, presione ENTRAR Por ejemplo, si quisiesemos que se ejecutase en nuestro equipo a una hora: C:Documents and Settingspepito>at 11:20 c:/ejemplo.bat Se ha agregado un nuevo trabajo con identificador = 1 Si queremos ver las tareas pendientes: C:Documents and Settingspepito>at Estado ID Día Hora Línea de comando ----------------------------------------------------------------------- 1 Hoy 11:20 c:/ejemplo.bat Si quisieramos eliminar esa tarea: at ombreDeEquipo id /delete | /delete/yes En nuestro caso, si tenemos nuestra tarea con el identificador 1. at 1 /delete Para mas información sobre el comando at, visitar http://support.microsoft.com/kb/313565/es También podemos visitar esta extensa colección de ejemplos. 3. Shell de LINUX. Historia y Conceptos básicos La Shell permite al usuario interactuar con el Kernel a través de la interpretación de los comandos que el usuario ingresa en la línea de comandos ( ó a través de los "scripts", archivos que ejecutan un conjunto de comandos). Si quieres saber qué Shells tienes instalados en tu distribución GNU/Linux sólo tienes que teclear el comando: cat /etc/shells ó cat /etc/shell (dependiendo de la distribución que tengas instalada). En mi caso, la salida de este comando es la siguiente: # /etc/shells: valid login shells /bin/ash /bin/bash /bin/csh /bin/sh /usr/bin/es /usr/bin/ksh /bin/ksh
  • 6. /usr/bin/rc /usr/bin/tcsh /bin/tcsh /usr/bin/zsh /bin/sash /bin/zsh /usr/bin/esh /bin/rbash /usr/bin/screen Para saber que tipo de Shell estamos usando, tecleamos el siguiente comando en una consola de Linux: root@ubuntu:~# echo $SHELL /bin/bash Para cambiar el tipo de Shell que se esta usando usaremo el comando: root@ubuntu:~# chsh Es importante también saber que un script puede ejecutarse en primer o en segundo plano: o Primer plano (foreground): se lanza introduciendo el nombre del script, pero hasta que el script no termine no se devolverá el control de la shell al usuario. o Segundo plano (background):se lanza igual pero añadiendo a continuación &. El control de la shell pasa inmediatamente al usuario( normalmente usado para procesos de larga duración) 3.1 Historia de las Shells La primera Shell fue programada por Steven Bourne (llamada por este motivo Bourne-Shell). Según las versiones se le llama sh o bsh. Es una shell muy limitada, y usa una sintáxis de comandos usada en los primeros sistemas UNIX. Cronológicamente, la siguiente shell fue la c-shell o csh, desarrollada por el unix BSD de Berkeley. Y cómo su nombre indica, usa comandos muy parecidos al lenguaje de programación C. También existe una shell llamada tcsh, que es una especie de c-shell mejorada, siendo capaz de chequear ficheros, completar nombres de variables, aliases. No suele venir incluida en las instalaciones estándar. En 1986, David Korn en los laboratorios AT&T programó la korn- shell (ksh) que nació de juntar lo mejor de la bourne shell y la c-shell. En la mayoría de los sistemas Linux, viene por defecto la shell bash (Bourne-Again-shell, en referencia al inventor de la primera Shell). Esta Shell posee toda la funcionalidad del sh con características avanzadas de C Shell, por eso cualquier script escrito para una shell sh correrá perfectamente. La shell bash fué programada por desarrolladores del proyecto GNU. La ventaja principal es su potencia y que es gratuita. Por este motivo nosotros usaremos esta shell . 3.2 Conceptos Básicos Para comenzar a introducirnos en el mundo de los scripts, recomendamos antes la lectura de estos artículos:  Editor VI , ya que necesitaremos manejarnos con este editor para escribir nuestros scripts...  La estructura del sistema de archivos en Linux , imprescindible si no se conoce el sistema de archivos de Linux.  Introducción a la Shell de Linux, dónde se hace un breve repaso a los comandos más básicos de Linux Antes de comenzar con ejemplos de Scripts, vamos a explicar una serie de conceptos, necesarios a la hora de implementar nuestros shell- scripts: 3.2.1 Variables Para asignar un valor a una variable:
  • 7. valor=7 Para visualizar el contenido de la variable root@ubuntu:~# echo $valor 7 Para borrar el contenido root@ubuntu:~# unset valor root@ubuntu:~# echo $valor A continuación se muestra una tabla con una serie de variables especiales que nos serán de utilidad a la hora de escribir nue stros scripts: VARIABLE DESCRIPCION $0 Nombre del Shell-Script que se está ejecutando. $n Parámetro o argumento pasado al Shell-Script en la posición n, n=1,2,... $PS1 Prompt $# Número de argumentos. $* Lista de todos los argumentos. $? Salida del último proceso ejecutado. $$ Número de identificación del proceso (PID) $! Número del último proceso invocado por la shell 3.2.2 Variables de entorno Existen dos áreas de memoria en las shells para almacenar variables, el Área local de datos y el Entorno. Podemos visualizar su contenido de ambas áreas, al igual que Windows, con el comando set. Por defecto, cuando asignamos un valor a una variable, es local, es decir, es conocida por esa shell, pero si se abre otra shell a partir de la que estamos, estas nuevas 'subshells' desconocen el valor de las variables que hemos asignado anteriormente. En cambio, las variables del entorno están disponibles para las subshells. Es decir los valores de estas variables son conocidos por los procesos hijos de la shell. Para hacer que una variable se almacene en el área de Entorno, se utiliza el siguiente comando: root@ubuntu:~# export nombre=javi Para ver la lista de variables del entorno usaremos el comando env. Debemos saber que una variable exportada NO es lo mismo que una variable global, sino una copia, ya que podrá ser modificada pero volverá a tener su anterior valor cuando salga de la subshell. Cómo ya sabemos, existe un conjunto de variables de entorno predefinidas, que a continuación listamos en esta tabla: COMANDO DESCRIPCION
  • 8. PATH Camino de búsqueda de órdenes HOME Directorio de trabajo del usuario USER Usuario que establecióla sesión PWD Ruta completa del directorio de trabajo actual LOGNAME Nombre del usuario que ejecuta la shell TERM Tipo de terminal. SHELL Shell que está ejecutándose PS1, PS2, PS3, PS4 Prompts 3.2.3 Entrecomillado Debido a que la shell bash puede usar nombres simbólicos que representan valores, como el path del directorio personal, necesitaremos conocer la diferencia entre los distintos tipos de entrecomillado, el simple, el doble y el uso de las sencuencias de escape (). Entrecomillado simple Nos sirve para hacer que la shell tome lo encerrado entre él como una expresión literal, ya sean variables, comodines u otras expresiones entrecomilladas. Es decir el contenido no es interpretado por la shell. Para entenderlo mejor, imaginemos que deseamos crear una carpeta de nombre * (asterisco). Si lo intentamos, es decir si tecleamos mkdir *, nos dará error. Sin embargo si escribimos mkdir '*', el intérprete de comandos tomará el carácter comodín (*) como un literal y no como un comodín, y podremos crear la carpeta con ese nombre. Entrecomillado doble Permiten la sustitución de parámetros, la sustitución de comandos y la evaluación de expresiones aritméticas, pero ignoran lo s caracteres tubería, sustituciones de tilde, expansión de caracteres comodines, aliases y la división de palabras vía delimitadores. Las comillas simples dentro de las comillas dobles no tienen efecto. Se puede incluir comillas dobles dentro de una cadena con comillas dobles anteponiendo . Es decir, se produce sustitución de variable (el signo del dolar se interpreta) por ejemplo, podremos ejecutar ls "$BASH" y nos devolverá correctamente el tipo de shell (/bin/bash), pero si hacemos ls "*", el comodin será tomado como un literal. Sencuencias de escape () Una barra inclinada inversa no entrecomillada, es decir , preserva el valor literal del siguiente carácter que lo acompaña. Para entenderlo mejor, veamos un ejemplo: root@ubuntu:~# echo $BASH /bin/bash Si utilizamos la encuencias de escape: root@ubuntu:~# echo $BASH $BASH Veamos otros ejemplos:
  • 9. root@ubuntu:~# usuario=javi root@ubuntu:~# echo $usuario javi root@ubuntu:~# echo "$usuario" javi root@ubuntu:~# echo '$usuario' $usuario root@ubuntu:~# echo $usuario $usuario root@ubuntu:~# echo "'$usuario'" 'javi' A continuación se muestra una tabla para que fácilmente veamos la diferencia entre un tipo de entrecomillado y otro: EXPRESIÓN VALOR $usuario javi "$usuario" javi '$usuario' $usuario $usuario $usuario " '$usuario' " 'javi' 3.2.4 Ejecución Existe dos formas de ejecutar los scripts: o Anteponiendo sh, source o bien "." al nombre del script. root@ubuntu:~# sh ejemplo.sh esto es un ejemplo o
  • 10. root@ubuntu:~# source ejemplo.sh esto es un ejemplo o root@ubuntu:~# . ejemplo.sh esto es un ejemplo o o Dando permiso de ejecución y a continuación, invocándolo con su nombre anteponiendo la ruta donde se encuentra el script : root@ubuntu:~# chmod +x ejemplo.sh root@ubuntu:~# ./ejemplo.sh o Si nos encontramos en el mismo directorio que el script : root@ubuntu:~# . ejemplo.sh esto es un ejemplo Sino pondremos la ruta, por ejemplo: root@ubuntu:~# /root/ejemplos/ejemplo.sh esto es un ejemplo En caso de que el directorio donde se encuentra el script este en el PATH, se podr ía ejecutar introduciendo simplemente el nombre. 3.2.5 Parámetros Un shell-script soporta argumentos o parámetros de entrada. Desde el interior del script se referencian mediante las variables especia les $i con i=1, 2, ..., NumeroArgumentos. Es decir, si lanzamos el siguiente script : root@ubuntu:~# ejemploScript uno dos gato Tendremos que el primer parámetro es uno, el segundo dos y el tercero gato, referenciándolos en el script como $1, $2 y $3 re spectivamente. Recordemos como ya vimos anteriormente que la variable $0 hace referencia al nombre del script. También podemos escribirlos en la shell con el comando "set": root@ubuntu:~# set parametro1 parametro2 parametro3 root@ubuntu:~# echo $2 parametro2 Con el comando "shift", podemos desplazar, es decir borrar varias posiciones:
  • 11. root@ubuntu:~# set parametro1 parametro2 parametro3 root@ubuntu:~# shift 2 root@ubuntu:~# echo $1 parametro3 Con "shift 2" hacemos que desaparezca el valor de $1 y $2, y que ahora $1 valga lo que estaba en $3. 3.2.6 Automatización de tareas con Crontab Crontab es una herramienta cuya función es la automatización de tareas. Por ejemplo podemos apagar un equipo a una hora determinada o realizar backups de manera automática. Para ver qué tareas tenemos en el crontab, deberemos ejecutar: root@ubuntu:~#crontab -l Veamos un ejemplo que ejecutaría el comando who todos los martes a las o nce y media de la noche, guardando la salida en fichero.txt:: 30 23 * * 2 /usr/bin/who >> /home/fichero.txt El formato de las entradas de crontab es el siguiente: [minutos] [hora] [día] [mes] [dia_de_semana] [comando] Teniendo en cuenta que:  Minutos: (0-59): Es el minuto exacto en el que quieres que se ejecute la tarea  Hora: (0-23) La hora exacta en formato de 24 horas  Día: (1-31) Valor numérico del día del mes  Mes: (1-12) Valor numérico del mes  Día de la semana: (0-6), siendo 1=Lunes, 2=Martes,... 6=sábado y 0=Domingo: Valor numérico del día de la semana  Usuario: usuario que ejecuta el comando, sino se pone, se usa root por defecto  Comando: comando a lanzar Para especificar todos los valores posibles de una variable se utiliza el asterisco (*). Para agregar, quitar o modificar tareas en el crontab usaremos: root@ubuntu:~#crontab -e que abrirá el editor (el que hayamos definido en la variable de entorno $EDITOR) y cargará el archivo crontab correspondiente al usuario que está logueado. Además con los siguientes comandos también podremos:  crontab -r: elimina el fichero crontab del usuario.  crontab -u usuario: aplica una de las opciones anteriores para un usuario determinado.  crontab fich: instala el fichero fich como crontab del usuario. Ahora veamos un ejemplo de cómo ejecutar nuestro script cada 20 minutos y que la salida se guarde en un log:
  • 12. 20 * * * * /home/script.sh >> mylog.log es importante no olvidar poner permisos de ejecución al script (con el comando chmod). Continuemos con este tutorial, ahora veremos los siguientes puntos: - SCRIPTS EN LINUX: Estructuras de control - SCRIPTS EN LINUX: Ejemplos de Scripts I. 4. Estructuras de control Cómo en cualquier lenguaje de programación, necesitaremos una serie de estructuras de control que permitan modificar el flujo de ejecución de las instrucciones de nuestro script. 4.1 If La sintaxis mas sencilla será: if condicion then [bloque de comandos] [else] [bloque de comandos] fi Si queremos añadir mas condiciones: if condicion1 then [bloque de comandos si la condición1 se cumple] elif condicion2 then [bloque de comandos si la condición2 se cumple] else [bloque de comandos comandos si no se cumplen ni la condición1 ni la condición2 ] fi Normalmente la condición será el resultado de evaluar una primitiva o de ejecutar un comando. Veamos un ejemplo: #!/bin/bash
  • 13. pin="1234" echo "Introduzca su pin" read -s clave if test "$clave" = "$pin" then echo "Pin correcto" echo "Acceso permitido" else echo "Pin incorrecto" fi En este sencillo ejemplo se nos pide que introduzcamos el pin (en nuestro caso lo hemos fijado a 1234), y dependiendo si lo introducimos bien o no, nos muestra una mensaje u otro. Más adelante veremos con mas profundidad las posibilidades del comando test. Evaluando expresiones según código de error: && y || Existe otra manera de evaluar condiciones mediante la utilización de los caracteres especiales && y ||, que usan los códigos de error de un comando. Es decir, cada comando ejecutado devuelve un valor de salida y como vimos, sacando el valor de '$?,' podíamos saber la salida del último proceso ejecutado. El operador '&&' ejecuta un comando, y si es correcto ejecuta el siguiente, veamos un ejemplo: #!/bin/bash if ls /var && ls /etc then echo "ok" else echo "error" fi En este caso para que salga de mensaje ok, se tendrá que haber podido listar el directorio /var y el /etc también, y sino dará error (esto puede ser usado cuando queremos comprobar la existencia de los directorios para nuestros script): El operador '||' ejecuta un comando y si no es correcto ejecuta el siguiente: #!/bin/bash if ls /var || ls /etc then echo "ok" else echo "error" fi En este caso saldrá el mensaje "ok" si se ha podido listar correctamente alguno de los directorios ( /var o /etc), o los dos.
  • 14. Comparación de ficheros y variables con test. Para evaluar expresiones condicionales dentro de los 'if' se usa el comando 'test'. Veamos un resumen en la siguiente tabla: EXPRESIONES DESCRIPCION -b fichero Cierto si fichero existe y es un dispositivo de bloques. -c fichero Cierto si fichero existe y es un dispositivo de caracteres. -d fichero Cierto si fichero existe y es un directorio. -e fichero Cierto si fichero existe. -f fichero Cierto si fichero existe y es un fichero normal. -g fichero Cierto si fichero existe y tiene el bit de grupo activado. -k fichero Cierto si fichero tiene el bit de sticky activado. -L fichero Cierto si fichero existe y es un enlace simbólico. -p fichero Cierto si fichero existe y es una tubería nombrada. -r fichero Cierto si fichero existe y es legible. -s fichero Cierto si fichero existe y su tamaño es mayor que cero. -S fichero Cierto si fichero existe y es un socket. -t [df] Cierto si df está abierto en un terminal. Si df es omitido, se toma 1 (salida estándar) por defecto. -u fichero Cierto si fichero existe y tiene el bit de usuario activo. -w fichero Cierto si fichero existe y es escribible. -x fichero Cierto si fichero existe y es ejecutable. -O fichero Cierto si fichero existe y es propiedad del identificador efectivo del usuario. -G fichero Cierto si fichero existe y es propiedad del identificador efectivo del grupo. fichero1 -nt fichero2 Cierto si fichero1 es más reciente (en base a la fecha de modificación) que fichero2. fichero1 -ot fichero2 Cierto si fichero1 es más antiguo que fichero2. fichero1 -ef fichero2 Cierto si fichero1 y fichero2 tienen el mismo número de dispositivo y de nodo-i. -z cadena Cierto si la longitud de cadena es cero. -n cadena Cierto si la longitud de cadena no es cero. cadena Cierto si la longitud de cadena no es cero. cadena1 = cadena2 Cierto si las cadenas son iguales. cadena1 != cadena2 Cierto si las cadenas no son iguales. ! expr Cierto si expr es falsa. expr1 -a expr2 Cierto si expr1 y expr2 son ciertas. expr1 -o expr2 Cierto si expr1 o expr2 son ciertas. arg1 OP arg2 OP es uno de los siguientes valores: -eq, -ne, -lt, -le, -gt, o -ge. Estos operadores
  • 15. binarios aritméticos devuelven cierto si arg1 es igual, distinto, menor que, menor o igual que, mayor que, o mayor o igual que arg2, respectivamente. arg1 y arg2 pueden ser enteros positivos, enteros negativos, o la expresión especial -l cadena, la cual significa la longitud de cadena.e Veamos un ejemplo: #!/bin/bash echo "dame primer número" read primero echo "dame segundo número" read segundo if test $primero -lt $segundo then echo $primero es menor que $segundo else if test $primero -gt $segundo then echo $primero es mayor que $segundo else echo $primero es igual que $segundo fi fi 4.2 For El bucle 'for' es una estructura de control iterativa que permite repetir una sección del programa, un número fijo de veces. Su estructura es así: for variable in [lista de palabras] do comandos done Otra manera de escribir nuestro bucle 'for' podría ser así: for variable in [lista de palabras]; do comandos; done Veamos un ejemplo, en el que nos ayudamos de la ejecución del comando seq para cargar la variable:
  • 16. #!/bin/bash for variable in `seq 1 100` do echo $variable done Conseguiremos como salida un listado de los 100 primeros números. 4.3 While Sirve para repetir un bucle mientras se cumpla la condición: While condición do comandos done Veamos en siguiente ejemplo donde creamos una sucesión de números desde un origen, en este caso el 33, hasta el final que marca la condición (el 100): #!/bin/bash num=33 while [ $num -le 100 ] do echo "numero: $num" num=`expr $num + 1` done 4.4 Until Igual que While pero el bucle se ejecuta mientras la condición sea falsa: Until condición do comandos done A continuación, el mismo ejemplo que el While, pero esta vez utilizando la estructura Until: #!/bin/bash num=33 until [ $num -eq 100 ] do echo "numero: $num" num=`expr $num + 1`
  • 17. done 4.5 Case Veamos la estructura: case variable in patron1) comandos condicion1;; patron2) comandos condicion2;; ... patron n) comandos condicion n;; *) comandos si no se cumplen ninguna;; esac En esta estructura cuando se encuentre un patron que coincida, se ejecuta la lista de comandos hasta los ';;' y se termina la ejecución de 'case'. Veamos un ejemplo: #!/bin/bash case $1 in start) echo "Arranco el servidor" ;; stop) echo "Paro el servidor" ;; restart) $0 stop $0 start ;; *) echo "Este script se arranca tecleando $0 start o $0 stop" ;; esac 4.6 Select A continuación se muestra la estructura:
  • 18. select nombre_de_variable [in lista] do comandos done El siguiente ejemplo guarda en el fichero "ejemploselect" el resultado del comando ls, que lista los archivos del directorio actual, y permite editarlo y salir: #!/bin/bash echo "Elige lo que quieres hacer " fichero=/home/ejemploselect ls > $fichero select opciones in listar editar salir do case $opciones in listar) cat $fichero ;; editar) vi $fichero ;; salir) break ;; esac done 5. SCRIPTS EN LINUX: Ejemplos de Scripts I. Ya esta bien de teoría, vamos a ver un par de scripts del mundo real. Uno de ellos nos servira para comprobar que nuestra red local de "miles" de servidores está funcionando. El segundo script sirve para automatizar la creación de usuarios y servirá de punto de partida para otro algo más complejo que veremos despues. 5.1 Script par realizar un "ping" a todas las máquinas de nuestro sistema. Supongamos que somos administradores o responsables de una red con cierto número de servidores y queremos realizar periodicamente la tarea de saber si están "levantados". Para ello escribiremos un script que lanzará un ping a todos nuestro servidores y nos avisará sonoramente cuando uno de ellos no responda. Lanzamos el "vi" y creamos el siguiente script que llamaremos ping.sh
  • 19. #!/bin/sh #### Defino una función con todas las operaciones para poder llamarla recursivamente. Las funciones no se ejecutan hasta que no #### se les llama o invoca ejecucion() { clear #####limpia la pantalla for server in `cat mis_servers.lst` #### Realiza un cat del fichero mis_servers.lst y almacena ciclicamente cada linea en la variable $server. Es decir realiza un for #### tantas veces como lineas tenga mis_servers.lst y almacena el contenido de la linea en la variable $server. Para cada ejecución #### del for realiza lo que está entre el do y el done. do echo echo Realizo un ping a la maquina $server echo ping -c 2 -A $server ### Manda dos paquetes de trafico icmp al destino almacenado en server. Emite un pitido si no hay respuesta. done ###Ahora dentro de la funcion voy a llamar a la propia funcion para convertir el proceso en un bucle. Colocare una pausa para ### espere 2 minitos antes de volver a ejecutarse sleep 120 ejecucion } ejecucion #### Esta llamada externa es la que se va a ejecutar la primera vez. Necesitamos crear un fichero "mis_servers.lst"con las ip de nuestros servidores:
  • 20. root@ubuntu:~# cat mis_servers.lst 192.168.1.37 192.168.1.1 192.168.1.89 Entonces al ejecutar nuestro script obtenemos: Realizo un ping a la maquina 192.168.1.37 PING 192.168.1.37 (192.168.1.37): 56 data bytes 64 bytes from 192.168.1.37: icmp_seq=0 ttl=128 time=0.244 ms 64 bytes from 192.168.1.37: icmp_seq=1 ttl=128 time=0.269 ms --- 192.168.1.37 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.244/0.257/0.269/0.013 ms Realizo un ping a la maquina 192.168.1.1 PING 192.168.1.1 (192.168.1.1): 56 data bytes 64 bytes from 192.168.1.1: icmp_seq=0 ttl=255 time=0.637 ms 64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=0.629 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.629/0.633/0.637/0.004 ms Realizo un ping a la maquina 192.168.1.89 PING 192.168.1.89 (192.168.1.89): 56 data bytes --- 192.168.1.89 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss 5.2 Script para crear usuarios en local Vamos a realizar un script que nos facilite la creación de usuarios en una máquina LINUX. Este script es muy bueno porque aunque ejecutado localmente tampoco nos ahorra demasiado tiempo, puede usarse de base para un script que cree usuarios en máquinas remotas. ####Creamos una función que recoja los datos necesarios para la creacion de usuarios ################################################## ######## ###FUNCION QUE RECOGE LOS DATOS##################### ################################################## ########
  • 21. peticion_datos() { #### Borramos el contenido de las variables que vamos a usar. Por precaucion. unset $user unset $grupo1 unset $grupo2 unset $shell unset $password unset $casa #### Vamos pidiendo los datos que necesitamos echo Nombre de usuario: read user ### Le proponemos al usuario el grupo "users", si no introduce ningun grupo, se lo asignamos nosotros echo Grupo principal:[users] read grupo1 if [ "$grupo1" = "" ] then grupo1=users fi #### Puede no especificarse un grupo secundario echo Grupo Secundario: read grupo2 if [ "$grupo2" = "" ] then grupo22="" else grupo22="-g '$grupo2'" fi ####Si no especifica una shell se le asigna /bin/bash echo Shell:[/bin/bash] read shell if [ "$shell" = "" ] then shell=/bin/bash fi ####Home del usuario, por defecto home/nombre_ususario echo Home del usuario: [/home/$user] read casa if [ "$casa" = "" ]
  • 22. then casa=/home/$user fi ####Existe el home?? Hay que crearlo??? echo Existe el home del usuario: [n] read exist if [ "$exist" = "" ] || [ "$exist" = "n" ] then param=-m fi #####Esta parte es la mas interesante. El comando useradd de linux permite especificar la password del usuario, pero debemos ###### encriptarla nosotros. Le pedimos la password al usuario del script y se la pasamos a un script de PERL. La salida ###### de dicho script la almacenamos en una variable. echo Password: read password contrasena=`perl /root/scripts/crypt.pl $password` #### El siguiente codigo es solo de control, para que muestre por pantalla el resultado de la encriptacion. echo ________________________ echo ----- DEBUG------------- echo ________________________ echo $contrasena } ################################################## ####################### ### FIN DE LA FUNCION ############################################### ################################################## ######################## ###### Como ya hemos especificado antes, las funciones no se ejecutan hasta que no se las llama. peticion_datos ####Ejecutamos el comando de creacion de usuario /usr/sbin/useradd -G $grupo1 $grupo22 -d $casa $param -p $contrasena $user
  • 23. El script de perl es muy sencillo. Debemos crearl el fichero crypt.pl en la misma ubicación del script de creación de usuarios. El contenido del fichero debe ser: #!/usr/local/bin/perl # # call it like so: perl crypt.pl password srand (time()); my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))"; my $salt = sprintf ("%c%c", eval $randletter, eval $randletter); my $plaintext = shift; my $crypttext = crypt ($plaintext, $salt); print "${crypttext}"; Podemos comprobar que funciona haciendo: root@ubuntu:~/scripts# perl crypt.pl funciona??? fFvYQ9cG.e.as Lo que nos devuelve es la cadena encriptada equivalente a "funciona???". Una vez que ya tenemos esto podemos probar la ejecución del script. Lo lanzamos y tenemos lo siguiente: Nombre de usuario: javi Grupo principal:[users] Grupo Secundario: Shell:[/bin/bash] Home del usuario: [/home/javi] Existe el home del usuario: [n] Password: javierete ________________________ ----- DEBUG------------- ________________________ ou47ezbisMOic Es muy comodo porque hemos incluido opciones por defecto lo que nos permite responder a casi todas las preguntas pulsando ENTER. Ahora vemos lo que ha originado el script.: FICHERO /etc/passwd: :::::
  • 24. ::::: gdm:x:108:118:Gnome Display Manager:/var/lib/gdm:/bin/false ubuntu:x:999:999:Live session user,,,:/home/ubuntu:/bin/bash sshd:x:109:65534::/var/run/sshd:/usr/sbin/nologin javi:x:1000:1001::/home/javi:/bin/sh FICHERO /etc/shadow: ubuntu:U6aMy0wojraho:13869:0:99999:7::: sshd:!:13869:0:99999:7::: javi:ou47ezbisMOic:13869:0:99999:7::: Observamos que la ejecución ha generado entradas en dos ficheros. En el fichero /etc/passwd se almacenan los datos del usuario y en el /etc/shadow se almacena la password. También se comprueba que se ha creado el directorio "home" del usuario: root@ubuntu:~/scripts# cd /home root@ubuntu:/home# ls -lrta total 0 drwxrwxrwt 30 root root 240 2007-12-22 11:22 .. drwxr-xr-x 21 ubuntu ubuntu 740 2007-12-22 11:32 ubuntu drwxr-xr-x 2 javi javi 140 2007-12-22 12:17 javi drwxr-xr-x 4 root root 100 2007-12-22 12:17 . Tutorial Shell Scripts III En esta última entrega veremos los siguientes puntos: 6. SCRIPTS EN LINUX: Un paso adelante : SSH sin contraseña, RSYNC y AWK. 7. SCRIPTS EN LINUX: Ejemplos de Scripts II. 7.1 Script para automatizar la réplica de una Base de Datos MySQL 7.2 Script para la creación de usuarios en varias máquinas remotas 6. SCRIPTS EN LINUX: Un paso adelante: SSH sin contraseña, RSYNC y AWK. Si habeis seguido el monográfico paso a paso, ya tendreis algunas nociones de teoría y habreis visto algunos ejemplos de scripts. Si ya nos sentimos comodos y no estamos muy perdidos, entonces estamos listos para dar un paso adelante. En este artículo del monográfico vamos a tratar, un poco por encima, tres nuevos aspectos teoricos. Vamos a ver como se puede realizar una conexión ssh entre dos equipos sin tener que introducir la contraseña y vamos a ver en que consisten Rsync y AWK, dos herramientas de los entornos Unix que nos darán nuevas posibilidades. SSH sin contraseña. No os asusteis, esto no significa que vayamos a tirar la seguridad de nuestra red por el suelo. Muy al contrario. Lo que vamo s a hacer es realizar una conexión entre dos equipos usando ssh, como método de autenticación usaremos un sistema clave publica / clave privada. Lo dicho... ¡empezamos!. Debemos determinar “que usuario de que máquina” se conectara a “que usuario de que otra máquina”.
  • 25. Debemos estar logados como ”usuario a” en la “máquina a”. Una vez en esta situación debemos hacer: ssh-keygen -t rsa Este comando nos creara una serie de archivos en la carpeta .ssh del home del “usuario a”. Uno de esos ficheros se llamará: $HOME/.ssh/id_rsa.pub Ahora debemos logarnos en el “equipo b” como “usuario b” y hacer un ftp al “equipo a”. Cuando se nos solicite el user/password para el ftp introducimos los del equipo a. ftp > lcd /tmp ftp> mget /home/usuario_a/.ssh/ id_rsa.pub ftp> bye Ahora ya tenemos el fichero en la carpeta /tmp del “equipo b”. cat /tmp/id_rsa.pub >> $HOME/.ssh/authorized_keys Con el comando anterior copiamos el contenido del fichero a un Nuevo fichero en la carpeta .ssh del usuario. El último paso es dar los siguientes permisos: chmod 0700 $HOME/.ssh/ chmod 0600 $HOME/.ssh/authorized_keys Ahora que ya hemos terminado la tarea, debemos probar que todo ha ido bien. Desde el equipo_a y como usuario_a hacemos: ssh usuario_b@equipo_b Esto debe permitirnos acceder sin contraseña. Debemos tener en cuenta que la primera vez que lo hagamos se nos solicitará incluir el equipo remoto en el fichero known_hosts. Tecleamos yes y tenemos concluida la tarea. ¿Que nos permite esto? Pues muy facil, nos permite ejecutar comandos en máquinas remotas, y nos permite hacerlo en un script programado en el tiempo, ya que no requiere que ningún administrador inserte la contraseña en la máquina remota .Un ejemplo, gracias a e sta forma de conexión podriamos centralizar la ejecución de copias de seguridad sin tener que programar todas ellas. Programariamos un script en un servidor que fuese lanzando las copias de seguridad en todos los demas y capturando las "salidas" de las ejecuciones en un solo log. Veremos tambén como gracias a esta utilidad podemos adecuar el script que ya hemos visto de creación de usuarios para que sirva para crear usuarios en máquinas remotas.
  • 26. RSYNC Es una utilidad típica de los sistemas UNIX. Lo primero que debemos hacer es saber si la tenemos instalada ya en nuestra distribución linux. Lo más facil para saber si esta instalada es ejecutarla desde linea de comandos y ver que pasa. Si está instalado nos saldrá el típico mensaje de créditos y opciones de uso: javi$ rsync rsync version 2.6.3 protocol version 28 Copyright (C) 1996-2004 by Andrew Tridgell and others <HTTP: rsync.samba.org /> Capabilities: 64-bit files, socketpairs, hard links, symlinks, batchfiles, inplace, IPv6, 32-bit system inums, 64-bit internal inums rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public Licence for details. rsync is a file transfer program capable of efficient remote update via a fast differencing algorithm. Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST or rsync [OPTION]... [USER@]HOST:SRC DEST .... ..... Pero bueno, al grano, ¿qué es Rsync? o mejor aun ¿para qué sirve?. Rsync nos va a permitir sincronizar carpetas dentro de una misma máquina o en máquinas diferentes. Esto, que así dicho no parece muy espectacular es muy útil. Aunque la cantidad de usos y parametros para usarlo es enorme , la manera más frecuente de usarlo es: rsync -avz user_remoto@ip_serv_remoto:/carpeta_remota /carpeta_local Con el anterior comando lo que hacemos es sincronizar la carpeta del servidor remoto con nuestra carpeta local. Estas dos operaciones las haremos usando el algoritmo que contiene rsync. Nos traeremos o llevaremos los ficheros y carpetas que no existan en la carpeta destino, o que aún existiendo sean versiones anteriores. Imaginaos lo útil que es esto para hacer copias de seguridad. Basta con que programemos un rsync para asegurarnos que una carpeta en un equipo tendrá siempre el mismo contenido que otra carpeta en otro equipo. Con respecto al tema de las comunicaciones, rsync tiene una buenisima funcionalidad ya que permite que lo utilices sobre una conexión ssh (cifrada). Para hacerlo basta con usarlo de la siguiente manera: rsync -avz -e 'ssh -i /user/.ssh/id_rsa' user@ip_serv_remoto:/carpeta_remota /carpeta_local/ ej: rsync -avz -e 'ssh -i /root/.ssh/id_rsa' root@192.168.17.100:/tmp/bbdd_dump /tmp/ >> /root/scripts/import.log Con esta forma de usarlo, al montarlo sobre una conexión ssh, podremos efectuar la operación sin tener que introducir la contraseña del sistema remoto (siempre que hayamos hecho una distribucion de clave pública). Esto nos permitirá usar rsync en nuestros scripts programados. En los
  • 27. ejemplos siguientes hay un ejemplo muy claro del uso del rsync para, por ejemplo, automatizar copias de seguridad o respaldo de bases de datos. AWK AWK es en si mismo todo un lenguaje de programación diseñado para tratar con textos. No nos adentraremos mucho en él (tiene infinitas posibilidades). Veremos como podemos usarlo para tratar cadenas de texto en nuestros scripts. Supongamos un caso en el que queramos obtener la fecha en el sistema de unos ficheros en un directorio. Todos sabemos que haciendo en la shell: # ls -lrta obtenemos algo como: root@ubuntu:~# ls -lrta total 400 -rw-r--r-- 1 javi javi 580 Sep 5 2005 htaccess.txt lrwxr-xr-x 1 root javi 54 Jan 11 2007 Enviar registro -> /Users/javi/Library/Assistants/Send Registration.setup drwxr-xr-x 5 javi javi 170 Jan 11 2007 Public drwxr-xr-x 5 javi javi 170 Jan 12 2007 Sites -rw-r--r-- 1 javi javi 3 Jan 12 2007 .CFUserTextEncoding drwx------ 17 javi javi 578 Mar 16 2007 .aMule -rw-r--r-- 1 javi javi 2611 Mar 22 2007 configuration.php -rw-r--r-- 1 javi javi 14451 Mar 30 2007 template_css.css drwxr-xr-x 3 javi javi 102 Apr 1 2007 PoisonDownloads -rw-r--r-- 1 javi javi 9455 Apr 3 2007 upload.gallery.php -rw-r--r-- 1 javi javi 3885 Apr 3 2007 show.gallery.html.php -rw-r--r-- 1 javi javi 3332 Apr 3 2007 authEA.php drwxr-xr-x 3 javi javi 102 Apr 20 2007 Shared Si sobre la salida del comando invocamos awk, podemos hacer algo como: root@ubuntu:~# ls -lrta |awk '{print ($6)}' Sep Jan Jan Jan Jan Mar Mar Mar Apr Apr Apr Apr Apr Es decir, le estamos diciendo que, sobre la salida del primer comando , imprima solo la 6ª columna. Podemos imprimir varias columnas haciendo:
  • 28. root@ubuntu:~# ls -lrta |awk '{print ($6 $7)}' Sep5 Jan11 Jan11 Jan12 Jan12 Mar16 Mar22 Mar30 Apr1 Tambien podemos agregar "literales": root@ubuntu:~# ls -lrta |awk '{print ("mes="$6" dia=" $7)}' mes= dia= mes=Sep dia=5 mes=Jan dia=11 mes=Jan dia=11 mes=Jan dia=12 mes=Jan dia=12 mes=Mar dia=16 mes=Mar dia=22 mes=Mar dia=30 mes=Apr dia=1 Si queremos tratar un fichero con información tabulada, en el que sabemos que en lugar del "espacio" se ha usado un separador como "|" ó ":" ó "," podemos especificarlo. Supongamos el siguiente fichero: root@ubuntu:~# cat fich_separadores javier:martinez:7-8-1979:Sevilla cristina:cacho:31-3-1979:Madrid luis:lopez:2-2-1982:barcelona Podemos generar una salida con el nombre y la ciudad de nacimiento sin más que indicarle al awk que el separador de campos e s el caracter ":" : root@ubuntu:~# cat fich_separadores |awk -F":" '{print ($1 " " $4)}' javier Sevilla cristina Madrid luis barcelona Veremos un ejemplo de un uso útil del AWK en uno de los scripts que vienen a continuación. 7. SCRIPTS EN LINUX: Ejemplos de Scripts II. Ahora vemos dos scripts interesantes que incluyen la última tería vista. Considero que son muy útiles y que pueden haceros la vida más fácil si los adaptais a vuestras necesidades. ¡Vamos alla!. 7.1 Script para automatizar la réplica de una Base de Datos MySQL
  • 29. Supongamos un escenario en el que tenemos dos servidores distintos. Uno de ellos tiene una aplicación con su correspondiente base de datos (puede ser una página web...). El otro servidor lo tenemos como servidor de emergencia. es decir, tenemos una copia de la aplicación y la Base de Datos, listo para ocupar el puesto del otro si se rompe o si hay que someterle a mantenimiento. Si la aplicación sufre pocas modificaciones o pocos "despliegues" nuevos, no será dificil abordar la tarea de realizar las modificaciones en los dos servidores cada vez. Sin embargo la Base de datos tendra muchas inserciones y modificaciones cada día. Con el siguiente script podremos automatizar la tarea de llavar parejas las dos bases de datos. Tenemos dos servidores. El servidor A es el de producción, y el servidor B es el que queremos mantener igual que el de producción. Antes de que este script pueda funcionar deberemos haber preparado la conexión del equipo A con el B a traves de SSH basado en clave publica / claver privada. SERVIDOR A. /root/scripts/export_bbdd.sh ### Almacenamos la fecha en una variable, luego la usaremos FECHA=`date '+%d_%m_%y'` ### Nos situamos en el directorio donde guardaremos el export de la BBDD cd /tmp/bbdd_dump #### Borro los export que pudiese haber almacenados rm -Rf export_* #### Genero el export, componiendo el nombre del fichero con la fecha. Es decir el fichero de exportación de la BBDD tendrá la forma "export_dd_mm_yyyy" y de esa forma siempre tendrá un nombre distinto. mysqldump -uroot -pcontraseña --add-drop-table nombre_bbdd > /tmp/bbdd_dump/export_$FECHA.sql ####Controlo los posibles errores en la ejecución. Esto equivale a preguntarle al sistema si ha ido bien la ejecución del último comando. if [ $? -eq 0 ] then echo La BBDD se ha exportado con exito. >> /root/scripts/export.log else echo ERROR EN LA EXPORTACION DE LA BBDD!!! LA SALIDA DEL COMANDO HA SIDO DISTINTA DE 0.!!! >> /root/scripts/export.log exit fi #####Escribo una marca con la fecha en el log del proceso. echo "El export del dia $FECHA se ha realizado con exito" >> /tmp/bbdd_dump/export.log #### Una vez hecho el export, puedo hacer que empiece la importación en la maquina remota. ssh root@192.168.17.102 '/root/scripts/import_bbdd.sh' >>/tmp/bbdd_dump/export.log
  • 30. SERVIDOR B. /root/scripts/import_bbdd.sh echo >> /root/scripts/import.log echo "################################################## ##############" >> /root/scripts/import.log echo >> /root/scripts/import.log FECHA=`date '+%d_%m_%y'` echo FECHA DE LA EJECUCION: $FECHA >> /root/scripts/import.log ######Nos situamos en el directorio desde donde importaremos el fichero sql que se ha generado en el anterior proceso. cd /tmp/bbdd_dump rm -rf * ###### Control de errores if [ $? -eq 0 ] then echo El borrado del sql anterior se ha realizado con exito. >> /root/scripts/import.log else echo ERROR EN EL BORRADO DE FICHEROS!!! LA SALIDA DEL COMANDO HA SIDO DISTINTA DE 0.!!! >> /root/scripts/import.log exit fi ##### Aquí nos traemos los ficheros que se han generado en el primer proceso. rsync -avz -e 'ssh -i /root/.ssh/id_rsa' root@192.168.17.100:/tmp/bbdd_dump /tmp/ >> /root/scripts/import.log ##### Control de errores if [ $? -eq 0 ] then echo El rsync se ha realizado con exito. >> /root/scripts/import.log else echo ERROR EN EL RSYNC!!! LA SALIDA DEL COMANDO HA SIDO DISTINTA DE 0.!!! >> /root/scripts/import.log exit fi ###### Importación en la bbdd del fichero que nos hemos traido. mysql -uroot -pcontraseña --database nombre_bbdd < /tmp/bbdd_dump/export*.sql >> /root/scripts/import.log if [ $? -eq 0 ] then echo La importacion del sql se ha realizado con exito. >>
  • 31. /root/scripts/import.log else echo ERROR EN LA IMPORTACION DEL SQL. LA SALIDA DEL COMANDO HA SIDO DISTINTA DE 0. >> /root/scripts/import.log exit fi En general, si usamos un script para una tarea medianamente crítica es importante redirigir la salida del mismo a un fichero de log y controlar bien los errores generando comentarios en el log que nos permitan conocer o saber los distintos pasos " correctos" que ha ido dando nuestro script. 7.2 Script para la creación de usuarios en varias máquinas remotas Este script es muy parecido al que ya habiamos visto. Para poder ejecutarlo automáticamente contra máquinas remotas deberemos haber preparado las conexiones ssh basadas en clave pública / clave privada desde el servidor que ejecuta el script a los servidores donde querem os administrar (crear) los usuarios. echo ------------------------------------------------------------------------------------- -- echo ------- SCRIPT PARA LA ADMINISTRACION CENTRALIZADA DE USUARIOS ---------------------- echo ------------------------------------------------------------------------------------- -- echo ################################################## ######## ###FUNCION QUE RECOGE LOS DATOS########################### ################################################## ######## # # peticion_datos() { ######## "Limpio" los posibles valores de las variables que voy a usar. unset $user unset $grupo1 unset $grupo2 unset $shell unset $password unset $casa ######### Comienzo a pedirle datos al usuario. En muchos de los campos se le ofrecen opciones por defecto. echo Nombre de usuario: read user echo Identificador de Usuario read ID
  • 32. echo Grupo principal:[users] read grupo1 if [ "$grupo1" = "" ] then grupo1=users fi echo Grupo Secundario: read grupo2 if [ "$grupo2" = "" ] then grupo22="" else grupo22="-g 'grupo2'" fi echo Shell:[/bin/bash] read shell if [ "$shell" = "" ] then shell=/bin/bash fi echo Home del usuario: [/home/$user] read casa if [ "$casa" = "" ] then casa=/home/$user fi echo Existe el home del usuario: [n] read exist if [ "$exist" = "" ] || [ "$exist" = "n" ] then param=-m fi ######### Aquí se le pide la password. Esto ya lo habiamos visto en un script anterior. Hace falta disponer del crypt.pl echo Password: read password contrasena=`perl /root/scripts/crypt.pl $password` ########Se muestra la contraseña encriptada para comprobar que el script de perl está funcionando correctamente. echo ________________________ echo ----- DEBUG------------- echo ________________________ echo $contrasena }
  • 33. ################################################## ####################### ### FIN DE LA FUNCION ############################################ ### ################################################## ######################## ################################################## ######################## ### FUNCION QUE GENERA EL COMANDO ######################### ################################################## ######################## generar_comando() { comando="/usr/sbin/useradd -u $ID -G $grupo1 $grupo22 -d $casa $param -p $contrasena $user" } ################################################## ####################### ### FIN DE LA FUNCION ############################################ ### ################################################## ######################## echo En esta opcion podra crear un usuario en maquinas remotas. Puede crearlo en una maquina, en una zona o en todas las maquinas. echo Para poder ejecutarse correctamente, la maquina remota debe tener dado de alta el usuario troya con los permisos correspondientes. echo echo Especifique si desea realizar la operacion contra una maquina "(1)", contra una zona "(2)": ####Esta parte esta muy bien. Se le ofrece al usuario la opcion de ejecutar la accion contra un ordenador ###### o contra una lista de ordenadores. Las listas son ficheros almacenados en un directorio que en nuestro ######caso denominamos zonas.
  • 34. read opcion case $opcion in 1) echo inserte el nombre o la ip del servidor: read server peticion_datos generar_comando ssh root@$server "$comando" echo $comando ;; 2) echo Las zonas definidas son: ### Accedo a al directorio de zonas y me quedo con los nombres de los ficheros que en el se encuentran cd zonas echo `ls -lrta |grep "-r" |awk '{ print $9 }'` echo echo Seleccione la zona sobre la que actuar: read zona peticion_datos for server in `cat $zona | awk -F"|" '{print $1}'` #### Esto se interpreta: "Para cada ip almacenada en la primera columna del fichero, usando de separador "|", haz lo que sigue." do echo Estoy con la maquina $server ### Para controlar en la pantalla en que servidor andamos generar_comando ssh root@$server "$comando" echo $comando done ;; *) echo La opcion elegida no es correcta echo ..........Saliendo............. exit ;; esac Si se ha seguido con detenimiento el script os dareis cuenta que las llamadas "zonas"deben definirse en un fichero almacenado en una carpeta /zonas que "cuelga" de la ubicación del script. Los ficheros de listas de servidores que se almacenan en dicha carpeta deben seguir la siguiente estructura: 192.168.1.33|Ordenador bbdd mysql 192.168.1.43|Servidor web
  • 35. 192.168.1.75|Servidor de correo Viendo la estructura del script no os será nada dificil el ir añadiendo funcionalidades tales como borrar usuarios, consultar los usuarios de un servidor etc...