HOWTO Shell Script
HOWTO Shell Script
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
explicaremos el Crontab para la automatización de tareas, ¿estas preparado?...pues
comenzamos..
2. Shell en Windows
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 en 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:
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 haga una copia de seguridad de ciertas
carpeta. Pues esta tarea es tan sencilla como crear un archivo ejemplo.bat con el
siguiente contenido.
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 /?.
at
ombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,...
comando
Tendríamos que seguir los siguientes pasos para crear nuestra tarea programada:
at
NombreDeEquipo hora /interactive | /every:fecha,... /next:fecha,... comando
at
ombreDeEquipo id /delete | /delete/yes
at 1 /delete
Si quieres saber qué Shells tienes instalados en tu distribución GNU/Linux sólo tienes
que teclear el comando:
Para saber que tipo de Shell estamos usando, tecleamos el siguiente comando en una
consola de Linux:
root@ubuntu:~# chsh
3.2.1 Variables
Para asignar un valor a una variable:
valor=7
A continuación se muestra una tabla con una serie de variables especiales que nos serán
de utilidad a la hora de escribir nuestros 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
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
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.
root@ubuntu:~# usuario=javi
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:
root@ubuntu:~# sh ejemplo.sh
esto es un ejemplo
○
root@ubuntu:~# source ejemplo.sh
esto es un ejemplo
root@ubuntu:~# . ejemplo.sh
esto es un ejemplo
○
○ Dando permiso de ejecución y a continuación, invocándolo con su
nombre anteponiendo la ruta donde se encuentra 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
Con "shift 2" hacemos que desaparezca el valor de $1 y $2, y que ahora $1 valga lo que
estaba en $3.
root@ubuntu:~#crontab -l
Veamos un ejemplo que ejecutaría el comando who todos los martes a las once y media
de la noche, guardando la salida en fichero.txt::
30 23 * * 2 /usr/bin/who >> /home/fichero.txt
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.
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
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
#!/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.
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.
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):
#!/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.
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.
-t [df] Cierto si df está abierto en un terminal. Si df es omitido, se toma 1 (salida estándar) por defecto.
-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 -ef fichero2 Cierto si fichero1 y fichero2 tienen el mismo número de dispositivo y de nodo-i.
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
----------------------------EJEMPLOS ISAAC-------------------------------
if test -f $DPSERVER_RAIZ/paquetesDPSERVERActualizacion.tar.gz
then
mv $DPSERVER_RAIZ/paquetesDPSERVERActualizacion.tar.gz
$DPSERVER_RUTA_INSTALACION
else
echo "Error. Paquete
$DPSERVER_RAIZ/paquetesDPSERVERActualizacion.tar.gz NO ENCONTRADO."
echo "Saliendo . . ."
sleep 3
exit 1;
fi
------
if test -d $DPSERVER_KEY
then
echo
else
mkdir private
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
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
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
4.6 Select
A continuación se muestra la estructura:
#!/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
###Creamos una función que recoja los datos necesarios para la creacion de usuarios
#########################################################
##FUNCION QUE RECOGE LOS DATOS#####################
#########################################################
eticion_datos()
### Borramos el contenido de las variables que vamos a usar. Por precaucion.
nset $user
nset $grupo1
nset $grupo2
nset $shell
nset $password
nset $casa
### Vamos pidiendo los datos que necesitamos
####Esta parte es la mas interesante. El comando useradd de linux permite especificar la password del usuario, pero
ebemos
##### encriptarla nosotros. Le pedimos la password al usuario del script y se la pasamos a un script de PERL. La
alida
##### de dicho script la almacenamos en una variable.
cho Password:
ead password
ontrasena=`perl /root/scripts/crypt.pl $password`
### El siguiente codigo es solo de control, para que muestre por pantalla el resultado de la encriptacion.
cho ________________________
cho ----- DEBUG-------------
cho ________________________
cho $contrasena
########################################################################
## FIN DE LA FUNCION ###############################################
#########################################################################
##### Como ya hemos especificado antes, las funciones no se ejecutan hasta que no se las llama.
eticion_datos
###Ejecutamos el comando de creacion de usuario
usr/sbin/useradd -G $grupo1 $grupo22 -d $casa $param -p $contrasena $user
#!/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}";
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:::
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 .
6. SCRIPTS EN LINUX: Un paso adelante: SSH sin
contraseña, RSYNC y AWK.
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.
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 esta 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:
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:
# ls -lrta
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:
Es decir, le estamos diciendo que, sobre la salida del primer comando , imprima solo la
6ª columna. Podemos imprimir varias columnas haciendo:
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:
Podemos generar una salida con el nombre y la ciudad de nacimiento sin más que
indicarle al awk que el separador de campos es 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.
SERVIDOR A. /root/scripts/export_bbdd.sh
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
SERVIDOR B. /root/scripts/import_bbdd.sh
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'
[email protected]:/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
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.
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 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
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)
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
http://es.wikipedia.org/wiki/Rsync
http://cm.bell-labs.com/cm/cs/awkbook/
http://es.wikipedia.org/wiki/AWK
http://es.wikipedia.org/wiki/Secure_Shell
http://www.openssh.com/es