0% encontró este documento útil (0 votos)
35 vistas31 páginas

105 Shells, Scripting y Gestión de Datos

Este documento discute la configuración del entorno de la consola, incluyendo variables como PS1 y archivos de configuración como bashrc. También cubre la creación de variables de entorno y aliases para personalizar la interfaz de usuario y facilitar el uso de comandos.

Cargado por

elmanuele
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
35 vistas31 páginas

105 Shells, Scripting y Gestión de Datos

Este documento discute la configuración del entorno de la consola, incluyendo variables como PS1 y archivos de configuración como bashrc. También cubre la creación de variables de entorno y aliases para personalizar la interfaz de usuario y facilitar el uso de comandos.

Cargado por

elmanuele
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 31

EN ESTE CAPÍTULO SE ABARCAN LOS SIGUIENTES OBJETIVOS DEL

EXAMEN:
•105.1: Personalizar y utilizar el entorno de la consola (4)

•105.2: Programar shell scripts (4)

•108.3: Funcionamiento y configuración del correo electrónico (3)

•105.3: Administración básica de datos SQL (2)

El entorno de Consola, Shell Scripts,


el Correo Electrónico y uso básico de
SQL

Administrar el entorno de la consola

Los archivos de configuración del entorno pueden clasificarse de la siguiente manera:

Entonces, explicando brevemente la tabla anterior, diríamos que si queremos configurar el diseño de
un prompt que afecte a todos los usuarios del sistema, deberíamos de definir la variable PS1 en el
archivo /etc/bashrc (o /etc/bash.bashrc, dependiendo de la distribución) que es el archivo que contiene
el valor para PS1. De este modo el prompt cambiará tanto si accedemos en un modo de ejecución de
consola como si accedemos en un runlevelgráfico y posteriormente abrimos una terminal, pero… ¿Por
qué también si accedemos directamente en un modo de solo consola si es /etc/profile el que se ejecuta
y no /etc/bashrc? – Porque si nos fijamos en el contenido de /etc/profile veremos que llama
a /etc/bashrc y entonces este setea el prompt para el usuario.De este modo a menos que comentemos
las líneas de /etc/profile en las que se llama a /etc/bashrc en ambos casos el prompt cambiará y
además de forma global.
Si lo que queremos es que el nuevo valor de la variable PS1 solo afecte a un determinado usuario y
además únicamente cuando abre una terminal desde el entorno de escritorio, es decir el prompt no
cambiaría si accedemos en un modo de ejecución de modo consola, tendremos que definir la
variable PS1en el archivo ~/.bashrc del usuario en cuestión y además tendremos que comentar las
líneas de ~/.bash_profile (o ~/.profile dependiendo de la distribución) en las que se llama a ~/.bashrc.
De lo contrario el prompt cambiará esta vez solo para ese usuario, pero en ambos casos, es decir,
tanto si el usuario accede directamente desde el modo consola como si lo hace desde el entorno
gráfico a través de una terminal virtual.
Nota: Dependiendo de la distribución podremos o no encontrarnos con el archivo ~/.bashrc. De todos
modos podremos crearlo nosotros en /etc/skel de manera que cuando creemos un nuevo usuario, este
ya cuente con el archivo.
Al igual que las consolas poseen scripts de inicio, puede que también cuenten con scripts de
desconexión o logout. Estos scripts como suponemos, se ejecutan cuando el usuario se desconecta.
El script ejecutado normalmente es ~/.bash_logout el cual puede ejecutar programas para limpiar los
directorios temporales, eliminar claves de seguridad de la memoria o realizar otras tareas que incluso
nosotros mismos hayamos programado para que sean ejecutadas.
Advertencia: Debemos de comprobar que es lo que realiza este script o si hemos programado
algunos comandos para que sean ejecutados al desconectar, deberemos de tener en cuenta, que cabe
la posibilidad (muy frecuentemente) que tengamos mas terminales del mismo usuario abiertas, por lo
que si cerramos una y se ejecuta el script puede que eliminemos archivos que estamos usando en
otras terminales, o simplemente no queremos que sean eliminados hasta que la última sesión sea
cerrada.
Otro archivo de configuración de bash es ~/.inputrc. Este archivo sirve para personalizar la
configuración del teclado. La sintaxis básica de las líneas del archivo es:

combinación_de_teclas: acción_a_realizar

Si tenemos la sensación de que determinadas combinaciones de teclas no funcionan como deberían


funcionar en modo texto, es aconsejable investigar la configuración de este archivo.
Nota: La configuración de archivo ~/.inputrc no afectará a los programas que se ejecuten en X, aunque
sean programas en modo texto que se ejecuten dentro de ventanas Xterm.

Sobre la variable PS1


Hacer un pequeño inciso para comentar el valor de la variable PS1. La variable PS1 como hemos
mencionado, define el aspecto del prompt por ejemplo, para un prompt estándar el aspecto sería el
siguiente:

nebul4ck@LiMinCinn ~ $

Lo que indica que el usuario es nebul4ck, el equipo se llama LinMinCinn, nuestro directorio de trabajo
actual es nuestro home (~) y el caracter $ nos identifica como usuario estándar (# para root). En este
caso la variable PS1 tendría el siguiente valor:

PS1='\u@\h \W \$ '

Disponemos de las siguientes variables del sistema para modificar esto:


•Indicar la fecha del sistema: \d
•El nombre del la máquina: \h

•El shell que utilizamos: \s

•El nombre del usuario activo: \u

•La versión del bash: \v

•El directorio de trabajo: \w

•El número de histórico del comando ejecutado: \!

•Indicar $ para usuario estándar y # para root: \$

Definir variables y alias de comandos


Los scripts de bash que acabamos de recordar y otros nuevos que hemos mencionados sirven como
hemos visto para configurar un entorno, pero para ello se necesitarán comandos que ejecutar y
construir una cierta lógica que permita al archivo realizar determinadas acciones. A continuación vamos
a ver como declarar una variable de entorno y un alias de comando en un shell script y dejaremos para
la próxima sección el estudio de funciones y estructuras de las que nos serviremos para programar
un script en bash.
Recordemos también que las variables de entorno proporcionan los medios para pasar datos mediante
nombres a programas iniciados desde una consola. Quizás un programa necesite conocer el nombre
del ordenador, es por ello que existe una variable (y si no existe podremos crearla y exportarla para
nuestro entorno en los archivos de inicio de consola anteriormente estudiados) llamada $HOSTNAME.
Vamos a imaginar que esta variable no existiese en nuestro entorno y un programa de terceros señala
en su documentación que el programa necesitará del valor de la variable $HOSTNAME, el cual debe
de ser el nombre del equipo que ejecuta el comando. Pues bien para definir esta variable de entorno,
editaríamos el archivo ~/.bash_profile (o ~/.profile) declarando la variable de la siguiente manera:

HOSTNAME=freeser
export HOSTNAME

Nota: Si el valor de la variable contiene espacios es obligatorio encerrarlo entre dobles comillas.
En la primera línea declaramos la variable $HOSTNAME y en la segunda convertimos a la variable
local en variable de entorno de manera que en cuanto el script de inicio sea ejecutado, esa variable
estará disponible para cualquier programa.
Cuando exportamos una variable directamente desde la línea de comandos, el valor de esta solo
estará disponible para la terminal desde la que ha sido exportada, anulándose su valor en cuanto
cerremos la sesión o en cualquier otra terminal virtual.
Podemos hacer que una variable sea de solo lectura anteponiendo la palabra ‘readonly‘ al nombre de
la variable, de manera que su valor no pueda ser modificado pero si visualizado hasta que el proceso
que hace uso de ella (un script, un determinado shell o sesión…) haya finalizado, es decir, en teoría
una variable que se ha modificado para solo lectura no puede ser modificada ni eliminada hasta que el
proceso que la utiliza finalice.
Cuando definamos una variable en un shell script, no será necesario exportarla, si no que la
definiremos y posteriormente el programa irá haciendo uso de ella conforme se vaya necesitando. Una
variable debe de empezar por una letra o un guión bajo ‘_‘ pero no por un número. A este tipo de
variables simples se les conoce como escalares (scalar)
Podemos ver el valor de una variable concreta desde la línea de comandos así:

$ echo "$HOSTNAME"

Nota: Fijémonos en la importancia de preceder el nombre de la variable con el signo ‘$‘, algo que no se
debe de hacer cuando se declara o define.
Si lo que queremos es ver todas las variables definidas para un entorno utilizaremos el comando env.
Este comando dispone de un par de opciones útiles pero para listar todas las variables bastará con
invocarlo sin parámetro alguno:

nebul4ck@LiMinCinn ~ $ env
SSH_AGENT_PID=1872
TERM=xterm
SHELL=/bin/bash
USER=nebul4ck
USERNAME=n0name
LOGNAME=nebul4ck
PWD=/home/nebul4ck
HOME=/home/alberto
LANG=es_ES.UTF-8
...

Nota: La salida del comando env ha sido cortada ya que suele ser bastante extensa.
Podemos definir una variable para un único programa con env de la siguiente manera:

$ env DISPLAY=freeser.4sysadmins.es:0.0 nedit

Nota: En la mayoría de los casos podremos omitir el comando env


Esto provocará que el programa nedit intente iniciar usando la
pantalla :0.0 en freeser.4sysadmins.es en lugar de la pantalla local predeterminada o definida en la
variable $DISPLAY
Si queremos comenzar con un entorno vacío es decir, ignorando el entorno heredado, acompañaremos
a env del parámetro -i (–ignore-environment) y para anular el valor de una variable específica usamos -
u <nombre_variable> o –unset=nombre_variable.
Antes vimos como mostrar el valor de una variable mediante el comando echo. Otra forma de hacerlo
con env sería así:

$ env | grep NOMBRE_VARIABLE

Para terminar con las variables de entorno vamos a presentar una lista de las que quizás sean las más
conocidas o nos vayan a ser mas útiles:
•USER o USERNAME: Nombre de usuario actual

•SHELL: Contiene la ruta a la consola de comandos en uso

•PWD: Esta variable la mantiene el sistema y su valor es el directorio de trabajo actual. Por ello
puede ser utilizada por programas para buscar archivos cuando no se proporciona la ruta
completa.

•HOSTNAME: Como ya vimos anteriormente, esta variable contiene el nombre del equipo de
trabajo
•PATH: Es una variable cuyo valor es lo suficientemente importante como para abrir una brecha
de seguridad. Su cometido es contener rutas de directorios separados por el caracter ‘ :‘, por
ejemplo PATH=/bin:/sbin:/usr/bin:/usr/sbin:/home/nebul4ck/bin, este valor indicaría donde buscar
archivos ejecutables, de manera que el usuario pueda ejecutar aquellos programas que se
encuentran bajo estas rutas (sea cual sea su directorio de trabajo), ahorrando la necesidad de
escribir ./archivo_ejecutable. Se recomienda no añadir la ruta ‘.‘ (directorio actual) al valor de esta
variable, especialmente para el usuario root ¿Porqué? – Un usuario malintencionado podría crear
en un directorio que solemos frecuentar un programa llamado por ejemplo ‘ls‘ de manera que
cuando root invoque a ls en el directorio donde se encuentra el programa malicioso, este sea
ejecutado en vez de el comando ls del sistema. En el caso de que sea necesario para un usuario
normal, deberemos de colocar esta ruta al final del valor de la variable PATH

•HOME: El valor de esta variable es la ruta de nuestro directorio principal, y al igual que la
variable PWD, puede ser utilizada por programas

•MAIL: Su valor es la ruta del buzón de correo del usuario en cuestión, que suele ser /var/spool/
mail/nombreusuario

•LANG: Utilizada para guardar el idioma actual

•TZ: Indica la zona horaria que tenemos configurada o podemos emplearla precisamente para
eso, para configurar nuestra zona horaria en caso de que estemos usando un ordenador remoto

•LD_LIBRARY_PATH: Indica los directorios en los que los programas pueden encontrar archivos
de bibliotecas. Es similar a PATH pero en vez de ejecutables son librerías

•PS1: También hemos visto ya la función de esta variable, la cual define el prompt del sistema

•TERM: Indica la terminal en uso.

•DISPLAY: Otra variable ya vista, identifica la pantalla utilizada por X que suele ser :0.0. Este
valor puede ir precedido del nombre de un host remoto o cambiar a :1.0 por ejemplo si tenemos
dos sesiones de X abiertas (:0.0 para la primera sesión y :1.0 para la segunda).

•EDITOR: El editor de texto iniciado por defecto será aquel que conste en el valor de esta
variable.

Igual que definimos las variables podemos definir los alias de comandos, pero… ¿Que son o para que
sirve? – La principal ventaja de utilizar alias de comandos es la de crear una versión acortada de un
comando, para que cada vez que queramos que un comando actúe de determinada manera no
tengamos que escribirlo de forma completa. Vamos a ver esto con un ejemplo sencillo:
Supongamos que cuando ejecutamos ls -l, el listado que nos devuelve el comando es un listado de
directorios y archivos sin color, es decir el mismo color utilizado para las letras de la consola. Cabe la
posibilidad de listar el contenido de un directorio de forma que los archivos sean mostrado en
diferentes colores, para que a simple vista reconozcamos de que tipo de archivo se trata, por
ejemplo verde para ejecutables, azul para directorios, celeste para enlaces simbólicos, rojo con
fondo negro para enlaces rotos, amarillo con fondo negro para archivos de caracter, etc… ¿y como
conseguimos esto? – Para hacer que cada vez que ejecutemos el comando ‘ls’ a secas despleguemos
un listado en formato de una sola columna (con los permisos, propietario, fecha, etc..) en color y
ordenado por fecha descendente, haremos lo siguiente:

$ alias ls='ls -lt --color'

Así de sencillo es crear un alias.


Nota: Para utilizar este alias de forma persistente podremos definirlo en alguno de los archivos de
inicio de consola. Dependiendo si queremos que sea aplicado de forma global o local elegiremos uno u
otros archivos.

Los Arrays
Un array o vector es una variable que tiene asignado un conjunto de valores a los cuales podemos
acceder mediante su número de posición, el cual nos sirve como índice de valores. Podemos definir
un array de la siguientes maneras:
•Múltiples valores de forma simultánea:

$ array=(ford renault "mercedes benz" dacia vw bmw)

•De uno en uno:

$ array[0]=ford
$ array[1]=renault
$ array[2]="mercedes benz"
...

Nota: Los indices no necesariamente tienen que ser numéricos, por ejemplo sería válido también
definir los valores del array tal que así: $ array[primero]=ford, $ array[segundo]=renault, etc…
•Igualmente podemos añadir un nuevo valor al array:

$ array[6]=chevrolet

Para consultar todos o un valor específico del array:


•Consultar un valor concreto:

$ echo ${array[1]}
renault

•Mostrar todos los valores:

$ echo ${array[*]}
ford renault mercedes benz dacia vw bmw chevrolet

$ echo ${array[@]}
ford renault mercedes benz dacia vw bmw chevrolet
Programación de shell scripts
Ahora que ya sabemos ejecutar comandos desde la terminal o desde un script de inicio (la forma de
hacerlo es la misma), sabemos declarar variables y crear alias, vamos a estudiar la forma de crear
un script ejecutable que sea reconocido por el shell y realice una serie de tareas en base a estructuras
lógicas (expresiones condicionales), bucles y funciones.
Antes de comenzar ha crear un script, los cuales son archivos de texto plano, por lo que podremos
hacerlo mediante un editor de texto corriente, debemos de saber algunas características básicas. A
estas alturas no es una sorpresa saber que la consola bash es la mas utilizada en entornos Linux, al
menos es la que viene por defecto en la gran mayoría de distribuciones, por lo que algo normal puede
ser programar un script de consola para bash. No obstante un script de consola bash puede ser
ejecutado en tcsh y otros lenguajes de programación de consola, a menos que el script utilice
funciones muy específicas de una consola concreta (en este caso bash).

La línea shebang o hashbang


Shebang o hashbang es el nombre con el que se conoce a la primera línea por la que está formado
un script de consola (shell script de ahora en adelante), aunque también recibe otros nombres
como hashpling o poundbang. Antes de mostrar el formato de esta línea es interesante saber que a
través del caracter ‘#‘ podremos escribir líneas dentro de un shell script las cuales no serán ejecutadas
aunque si interpretadas por el kernel. Dicho esto pasamos a mostrar el contenido de esta primera línea
del shell script:

#!/bin/bash

Está línea esta formada por el caracter de comentario, por el signo de exclamación ‘!‘ y por una ruta.
Los dos primeros caracteres forman un código que le indica al kernel de Linux que se trata de
un script y que utilice el resto de la línea como ruta al programa que va a interpretar el script, bash en
nuestro ejemplo.
Nota: Es posible encontrar la ruta a otro interprete o incluso a /bin/sh que en la mayoría de las veces
no es mas que un enlace simbólico a la consola de la distribución, por lo que de esta manera nos
aseguramos de que el shell script va a ser interpretado. No obstante como comentamos antes, si tiene
funciones muy específicas de una consola concreta, mejor indicar a esta.

Ejecutando un shell script


Cuando finalizamos la programación de un shell script, llega el momento de ejecutarlo para ver sus
resultados. Existen diferentes formas de ejecutar un script cada cual con su debida implicación:
•Establecer con chmod los permisos de ejecución. Usaremos u para el usuario, g para el grupo
o a para todos:

$ chmod a+x myshell.sh

Nota: Las extensiones como ya sabemos no son necesarias en Linux pero si identificativas.
•Utilizando el programa de la consola seguido del nombre del script. Se recomienda utilizar la
forma del ejemplo anterior, aunque esto puede ser útil si no hemos conseguido modificar los
permisos con chmod:
$ bash myshell.sh

•Ejecutar el shell script con el comando exec. Si ejecutamos un programa a través de exec este
tomará el control del proceso de la terminal desde el que ha sido invocado y una vez finalice
el script o programa ejecutado la terminal se cerrará. Esto puede ser útil en determinadas
ocasiones aunque no es muy utilizado, por ejemplo cuando un script llama a otro y este a su vez
a otro y así… De esta manera el nuevo toma el control del proceso del anterior. Puede ser un
método útil para controlar los recursos dedicados a la ejecución de una seríe de script.

$ exec /opt/myshell.sh

Podemos hacer la prueba ejecutando por ejemplo nuestro editor de texto desde la consola. Veremos
que cuando cerremos el editor la terminal virtual será igualmente cerrada:

$ exec nedit

El comando exec lo estudiamos en el Capítulo 1 concretamente entre los comandos “Redirecciones y


Canalizadores“
•Otra forma de ejecutar un script es aplicarle source. Para ello se utiliza el propio
comando source o el caracter ‘.‘ tal que así:

$ source myshell.sh

$ . myshell.sh

De este modo el script se ejecuta en la consola actual y no se inicia una instancia nueva de la consola,
como sucede cuando se ejecuta un shell script introduciendo su nombre o utilizando el
comando exec (que si que inicia una instancia nueva aunque esta controle a la terminal desde la que
se ha ejecutado). Existen ciertas ventajas a la hora de ejecutar un script con source, por ejemplo, si
queremos que el script haga uso de las variables de entornos definidas en la consola (aunque no se
hayan exportado) desde la que se ha ejecutado, este deberá de ser llamado con source.
Nota: Por lo general, sólo las variables de entorno que se hayan exportado de forma explícita, estarán
disponibles para los script que se ejecuten.
Esto pasa igualmente si un script que ha sido ejecutado de forma digamos ‘convencional‘ y en el se
definen ciertas variables que se usarán a lo largo del programa. Si en un punto de este programa
llamamos a otro script y queremos que este haga uso de esas variables, este nuevo script deberá de
ser llamado con source.
Otra ventaja de ejecutar con source un script es que si este establece variables de entornos, estás
estarán disponibles para la consola desde la que se ha invocado al script. Esto es lo que ocurre
cuando se inicia una terminal y /etc/profile o ~/.bash_profile llaman
a /etc/bashrc o ~/.bashrcrespectivamente. Si nos fijamos en estos script de inicio de consola veremos
que se ejecutan así:

if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi

Esto produce que el entorno creado por profile pueda ser utilizado e incluso modificado por bashrc
También, ejecutar un script de esta manera evita la sobrecarga asociada a iniciar nuevas consolas, que
aunque suele ser imperceptible, podría requerir de recursos si este script llamara de forma normal a
múltiples scripts secundarios generando cada uno una nueva instancia de consola.
Otro dato y como último apunte, es interesante saber que al ejecutar un script con source se ejecuta en
el idioma de la consola que realiza la invocación, mientras que al ejecutar un script de la forma normal,
se usa el lenguaje de consola especificado en la línea hashbang.

Uso de variables en los shell scripts


Ya hemos estudiado como definir una variable de entorno y exportarla para que esté disponible en el
entorno local o global de los usuarios. Las variables de los shell scripts suelen utilizarse para facilitar la
modificación de estos en un futuro. Los shell script pueden usar variables que hayan sido pasadas
como parámetros, definidas internamente, extraídas del propio entorno del script o pasándoselas a
petición del propio script
Cuando llamamos a un shell script bastará normalmente con escribir su nombre (si se encuentre
dentro de alguno de las rutas que contiene el path), ejecutarlo con ./nombre_script.sh, con el programa
de consola (bash nombre-script.sh) o pasándoselo a source (source nombre-script.sh ó . nombre-
script.sh). Sea cual sea la forma de ejecutarlo podremos escribir tras el nombre una serie de palabras
a las que se le denominan argumentos de programa y de las que este hará uso durante su ejecución.
Para el siguiente ejemplo el valor de la primera palabra podremos recuperarla desde dentro
del scriptcon $1, el valor de la segunda palabra con $2 y así sucesivamente hasta $9. La
variable $0 indica el nombre del propio script:

$ ./myscript.sh Juán 24 Madrid

Hola me llamo Juán, tengo 24 años y vivo en Madrid.


Para recibir este mensaje tras la ejecución del script bastaría con que myscript tuviese el siguiente
contenido:

#!/bin/bash
echo "Hola me llamo $1, tengo $2 años y vivo en $3"

Importante: Podemos recuperar el número de parámetros pasados al comando mediante la


variable $#, con $* recuperamos todos los parámetros sin incluir a $0 (muestra su valor, no el número),
con $$ podemos conocer el PID que ha creado nuestro script y con $? recuperamos el código de
retorno del último comando ejecutado.
El comando shift desplaza los parámetros, de modo que lo que es $2 se convierte en $1, $3 pasaría a
ser $2 y así sucesivamente, menos $0 que no es alterado. Podríamos usar shift junto con
un bucle para examinar los parámetros que son pasados a un script.
Como siempre mediante un ejemplo lo veremos mas fácil. Supongamos que hemos ejecutado la
siguiente línea:

$ ./miscript.sh uno dos tres cuatro y cinco

Y que el contenido de myscript.sh es:

#!/bin/bash
echo "El número de parámetros es: $#" \\ Esta línea desplegará un 5
echo "Los valores de los parámetros son: $*" \\ El valor que despliega esta
línea es uno dos tres cuatro cinco
shift 3 \\ Con el comando shift indicamos que ahora el parámetro primero
sea $4, pues hemos hecho que empiece inmediatamente después de la tercera
posición
echo -e "Ahora que hemos usado shitf 3 el parámetro 1 es: $1 y el parámetro
2 es: $2 \\ Esto devuelve: cuatro cinco
echo "Ahora el número de parámetros es: $#" \\ Pues el número de parámetros
ahora es: dos (cuatro cinco)

Para definir una variable dentro del script basta con escribir nombre=valor:

MYVAR="Este es mi valor"

$ echo "$MYVAR"
Este es mi valor

Podemos concatenar variables así:

YO="Soy Juán"
años=" y tengo 24 años"
Todo="$YO$años"

echo "$Todo"
Soy Juán y tengo 24 años

También podemos hacer que valga la salida de un comando. Para esto deberemos de rodear el
comando con acentos graves tal que así:

COMANDO=`ls -l | cut -d" " -f1`

echo -e "$COMANDO\n"
total
lrwxrwxrwx
drwxr-xr-x
lrwxrwxrwx
...

Nota: El parámetro -e de echo como ya sabemos por el Capítulo 1, hace que se interpreten los
caracteres especiales en este caso \n inserta un salto de línea.
Otras formas de utilizar variables es a través del entorno donde se está ejecutando el script o que sea
este quien nos pida que la introduzcamos.
•Usando variables del propio entorno: Si sabemos que nuestro entorno (y si no lo sabemos lo
comprobamos con echo “$VARIABLE”) está utilizando una variable (por ejemplo $HOSTNAME)
podremos hacer uso de ella dentro del script y será reconocida, o bien si definimos como hemos
hecho en el método anterior ciertas variables y luego llamamos con source a otro script dentro de
este script que contiene a las variables, el segundo script (el que es llamado) podrá hacer uso de
estas variables igualmente.

•El script nos pide que introduzcamos un valor: Podemos hacer que el propio script sea quien
nos pregunte por algún valor que almacenará para utilizarlo como variable dentro de su
contenido. Podríamos conseguir esto con el comando read de la siguiente manera:
#!/bin/bash
echo "Introduzca un nombre sin apellidos: "
read nombre
echo "Introduzca una edad: "
read edad
echo "Introduzca su ciudad de nacimiento: "
read ciudad
echo -e "\nHola me llamo $nombre, tengo $edad años y nací en $ciudad \n"

Aritmética con variables


Si queremos realizar operaciones aritméticas en el shell (algunos shell antiguos cono sh no soportan
esto) podemos utilizar el siguiente formato:

$((expresión))

Expresión estará formado por cualquier valor numérico específico, variables que contengan valores
numéricos y operadores.

$ echo $((b=a*2))
$ b=$((a*2))

Esto desplegará el resultado de ‘b‘ que será el valor que contenga la variable ‘a‘ multiplicado por dos.
Tenemos que prestar atención a como declaramos la variable dentro de la expresión, que como vemos
no se antepone el signo ‘$‘, esto es porque el shell reconoce que al no ser un operador o valor
numérico se trata de una variable. Si la variable no está previamente definida o su valor no contiene un
valor numérico se le autoasigna el valor 0.
Algunos operadores aritméticos:
+ suma
* mutiplicación
– resta
/ división entera
% resto de la división entera
( ) agrupar operaciones. Al igual que en matemáticas esto fuerza a que el grupo sea resuelto en
primera instancia

Uso de expresiones condicionales


La expresión condicional literal:

“Si el valor de X es menor que el valor de Y, haz esto“


“Si el valor de X es igual a Y, entonces haz esto, o si no haz esto otro“
“Si esto es verdadero y esto otro no lo es, haz esto, si esto no es verdadero o esto si lo es, haz esto, y
si no es ninguno haz esto otro“
podríamos representarlo de la siguiente manera:
Si hablamos de dígitos:
if [ "$X" -lt "$Y" ]
then
echo "El valor de X es $X y es menor que el valor de Y que es $Y"
fi

Si lo que se comparan son cadena de caracteres:

if [ "$COCHE1" == "$COCHE2" ]
then
echo "El coche1 es de la misma fábrica que coche2. La fabrica es
Ford"
else
echo "La marca de los coches no coinciden"
exit 0
fi

Podemos alargar la estructura así:

if [ "$a" -eq "$b" ] && [ "$COCHE1" != "$COCHE2" ]


then
echo "A y B son iguales, y además coche1 y coche2 son distintos"
elif [ ! -f "$archivo" ] || [ $(($1*$2)) -eq "$c" ]
then
echo "No existe el archivo $archivo ó A es igual a B
else
echo "Ninguna de las condiciones anteriores se cumplen"
exit 0
fi

Nota: Podemos crear una estructura if a partir del comando test o incluso usarlo únicamente para
recuperar el valor de retorno de un comando y utilizarlo luego:

if test $n -le $N
then
echo "El número $n es menor o igual que $N"
fi

test -d /home/nebul4ck
if [ "$?" -eq "0" ]
then
echo "El directorio principal existe"
fi

Para terminar con if debemos de saber que podemos anidar diferentes if siempre y cuando los
cerremos todos debidamente, por ejemplo:

if [....]
then
if [....]
then
.......
else
if [....]
then
.......
fi
fi
else
.........
fi

Test condicionales con if:


-d fichero : cierto si fichero existe y es un directorio
-e fichero : cierto si fichero existe, independientemente del tipo que sea
-f fichero : cierto si fichero existe y es un fichero normal
-r fichero : cierto si fichero existe y se puede leer
-s fichero : cierto si fichero existe y tiene tamaño mayor que cero
-w fichero : cierto si fichero existe y es se puede escribir sobre él
-x fichero : cierto si fichero existe y es ejecutable
Condicionales de dígitos:
n1 -eq n2 : cierto si los enteros n1 y n2 son iguales
n1 -ne n2 : cierto si los enteros n1 y n2 no son iguales
n1 -gt n2 : cierto si el entero n1 es mayor que n2
n1 -ge n2 : cierto si el entero n1 es mayor o igual que n2
n1 -lt n2 : cierto si el entero n1 es menor que n2
n1 -le n2 : cierto si el entero n1 es menor o igual que n2
Condicionales para cadena de caracteres:
s1 = s2 : cierto si las cadenas de texto s1 y s2 son idénticas
s1 != s2 : cierto si las cadenas de texto s1 y s2 no son idénticas
Nota: Podemos aplicar el signo de exclamación ‘!‘ a las condicionales de dígitos o de test de archivos
para negar
s1 > s2 : cierto si la cadena de texto s1 es mayor que s2
s1 < s2 : cierto si la cadena de texto s1 es menor que s2
-n cadena : cierto si la longitud de la cadena de texto es distinta de cero
Condicionales con expresiones:
! expresion : cierto si expresion es falsa (negación)
expresion1 -a expresion2 : cierto si expresion1 y expresion2 son ciertas
expresion1 -o expresion2 : cierto si expresion1 o expresion2 son ciertas

Nota: Con && indicamos que se ejecute el siguiente comando en caso de que la ejecución del anterior
haya sido correcta (ls -lt && echo “Listado del directorio”) o bien implicamos a que la condición sea
verdadera solo si se cumplen todos los requisitos (como ya vimos en uno de los ejemplos anteriores).
Con || estamos diciendo que si el último comando dió error, se ejecute el siguiente ( mkdi /opt/notfound
|| echo “El comando no está bien escrito y falló” ) o bien la condición será cierta si uno u otro de los
requisitos es verdadero. Esto también lo vimos en un ejemplo superior.
Existe otra instrucción con la que podemos usar el valor de una variable o expresión y ejecutar una
acción solo en el caso de que el valor o expresión coincidan con un patrón. Esta estructura es case:

case palabra in
patrón1) comando(s);;
patrón2) comando(s);;
esac
Los patrones se pueden ampliar utilizando comodines y reglas de expansión. Además es posible incluir
una condición por defecto, es decir, en el caso de que palabra no coincida con ningún patrón, se
ejecute una determinada acción. Esto lo conseguimos utilizando un * como patrón por lo que deberá de
ir como última opción, de lo contrario se ejecutaría siempre.

Los bucles for, while y until


Los bucles son estructuras que le indican al script que realice la misma tarea repetidamente hasta que
se cumpla (o hasta que deje de cumplirse) una determinada condición.

for
El bucle for se ejecuta una vez para cada elemento que pasamos (variable, lista de nombres, salida de
un comando…). Cada elemento se le asigna como valor en cada iteracción o turno a una variable con
la que se realizarán diferentes acciones. Veamos esto con un ejemplo:

for i in negro blanco azul


do
echo "El color es $i"
done

Existe un comando muy útil a utilizar con for que nos permitirá crear una lista de número en función del
o los parámetros que le pasemos. Puede usarse para generar un número y compararlo con otro y
actuar de una determinada forma o compararlo con un parámetro pasado al script etc… se trata del
comando seq y su sintaxis es seq(x [y z])
•Si pasamos un solo parámetro a seq (for i in `seq 10`) se generará una lista de números que
comenzará con 1 y terminará en el número indicado, 10 en nuestro caso.

•Si pasamos dos parámetros a seq (for i in `seq 5 10`) se generará una lista de números que
comenzará en 5 y terminará en el 10 para nuestro ejemplo. Esto es útil si queremos ir creando un
sumatorio de $i con respecto al valor anterior.

•Por último cabe la posibilidad de pasar tres parámetros como parámetros tal que así : for i in
`seq 2 4 14` . El primer parámetro (2) indica el número por el que se comienza, el segundo
parámetro indica el incremento (4) y el tercer y último parámetro indica el número final a mostrar.
Nuestro ejemplo mostraría la siguiente columna de números (aquí la representamos en fila): 2 6
10 14

Nota: En estos ejemplos hemos usado la variable i pero podemos pasar cualquier palabra para usar
luego como variable.

while
While es otro tipo de bucle que se ejecuta mientras la condición que le pasemos sea cierta. Es útil
para comprobar la veracidad de reiteradas condiciones. Su forma básica es la siguiente:

while [ condición ]
do
comandos
done
Un ejemplo del bucle while en el que se ejecutará una acción mientras n sea menor o igual a 10:

n=1
while [ "$n" -le 10 ]
do
echo "$n"
((n++))
done

until
Para terminar con los bucles comentar until, que es igual que while pero al contrario, es decir, se
ejecuta hasta que la condición sea verdadera. Su sintaxis es igual a la de while.
En este caso, a diferencia de while vamos a ejecutar una acción hasta que n sea mayor o igual a 11. El
resultado es el mismo al del ejemplo anterior con while pero se interpreta al contrario:

n=1
until [ "$n" -ge 11 ]
do
echo "$n"
((n++))
done

Existen tres comandos que nos pueden resultar útiles cuando trabajamos con bucles y estos
son: break, continue y exit.
•break : Termina el bucle. Si existe un bucle dentro de otro, break provoca que salga del bucle
desde el que fue llamado pero no del bucle padre de este.

•continue : Salta o continua con la siguiente iteracción del bucle en el momento en el que es
llamado, es decir, no termina el bucle.

•exit : Termina la ejecución del script. Suele usarse con el valor 0 o 1 como parámetro para
devolver un código de retorno del propio script por si tuviese que ser evaluada su ejecución.

select
El bucle select nos permite mostrar un menú de forma fácil y poder interactuar con él. Es común el uso
de select junto a case de manera que se nos presente un menú y en función de la opción elegida
hagamos coincidir esa opción (patrón) con uno de las posibilidades de case y ejecutar una acción. Con
el siguiente ejemplo veremos esto fácilmente:

select i in listado home backup quit


do
case $i in
listado) ls -lt /opt/archivos;;
home) cd ~/; echo "Moviéndonos al directorio home...";;
backup) tar -cpvzf ~/backup.tar.gz /opt/archivos/*;echo
"Realizando backup de /opt/archivos...";;
quit) echo "Saliendo del programa...";exit 0;;
esac
done
Las funciones
Las funciones son muy útiles en la creación de shell script debido a que pueden ahorrarnos muchas
líneas de código repetidas a lo largo del script. Podría definirse función como una parte del script que
realiza una subtarea específica y que puede ser invocada por su nombre desde otra parte del script. La
condición para usar una función es que siempre preceda a la palabra que lo llama. Esto hace que en
numerosas ocasiones tras definir las variables de un script, se definan las funciones y a continuación
se desarrolle el script, de manera que al ir leyendo linea a línea, cuando se llame a una función por su
nombre el script se desplazará hacía la parte superior para llamar a la función, realizará las acciones
pertinentes y volverá a la línea donde fue llamada con el valor de retorno. Vamos a ver esto con un
ejemplo. Vamos a llamar una función a la que además se le va a pasar un argumento, esto no es
necesario pero si útil en muchos casos. Para crear un ejemplo sencillo bastaría con no pasarle ningún
parámetro:

retorna_valor() {
if [ -d "$directorio" ]
then
echo "El directorio $directorio existe"
else
echo "El directorio $directorio no existe"
fi
}
echo "Vamos a comprobar si existen una serie de directorios"
for directorio in "/home/a.coslada" "/home/p.merino" "/home/r.garcia"
do
retorna_valor "$directorio"
done

Correo electrónico
A diferencia de otros sistemas, en Linux el correo electrónico es uno de los servicios de red mas
importantes. Linux hace uso del correo electrónico para muchas de sus tareas. Además de estar
estrechamente ligado a las cuentas de los usuarios, el correo en Linux es utilizado por ejemplo para
informar de sus actividades programadas con cron, o enviar notificaciones sobre operaciones
realizadas por shell scripts, entre otras. El servidor de correo contiene los mensajes entrantes de cada
usuario, normalmente en /var/spool/mail, aunque como siempre, esto pueda variar en función de la
distribución que estemos usando. Deberemos de tener un conocimiento básico sobre su
funcionamiento, configuración y posibilidades (crear alias de correo, reenviar correos, configurar el
correo en aplicaciones clientes, etc…).
Existen varios protocolos para administrar el correo electrónico, siendo el mas común SMTP (Simple
Mail Transfer Protocol, Protocolo simple de transferencia de correo). En la mayoría de ocasiones se
utiliza SMTP como sistema de entrega de correo, por estar diseñado como sistema push (el sistema
emisor inicia la transferencia). No obstante en la etapa final del envío del correo se utilizan protocolos
de tipo pull (el sistema receptor inicia la transferencia) como POP (Post Office Protocol, Protocolo de
oficina de correos) o IMAP (Internet Message Access Protocol, Protocolo de acceso a mensajes de
Internet). Estos protocolos son útiles sobre todo cuando el sistema receptor es el equipo de un usuario,
el cual suele permanecer apagado en muchas ocasiones. La diferencia básica entre ambos protocolos
es que con POP descargaremos los mensajes a nuestro equipo y con IMAP podremos leerlos desde el
propio servidor.
Funcionamiento del correo electrónico
El método tradicional en Linux para enviar correo, es hacer que los programas locales se comuniquen
con el servidor de correos local, quién a través del protocolo SMTP reenviará el correo hacia el destino.
Los servidores SMTP son conocidos también como MTA, Agentes de Transferencias de Correos. De
esta manera en caso de que el servidor de envío SMTP se encuentre offline, el correo se pondrá en
cola y será enviado a sus destinos una vez que este vuelva a estar operativo. La mayoría de los
clientes de correo (MUA, Agentes de usuario de correo) ofrecen la opción de contactar directamente
con un servidor SMTP remoto al enviar el correo.
Un servidor SMTP puede hacer tanto de servidor (es decir recibe el correo de otro sistema) como de
cliente (envía un correo a otro sistema).
El protocolo SMTP permite que un mensaje pase por un número arbitrario de ordenadores. Un usuario
puede redactar un email que será enviado a su servidor SMTP local. Este servidor buscará a través de
los servidores DNS el destino y una vez localizado se procederá a la entrega.
Cada servidor de la cadena de transmisión alterará el correo añadiendo un encabezado que
proporcionará información sobre la ruta que ha tomado el correo. Los spammers y similares, falsifican
los encabezados del correo complicando enormemente el análisis de seguimiento.

Configurar el correo electrónico


Aviso: Esta sección queda fuera del alcance del examen LPIC-1, aún así se cree conveniente añadir
algunos comentarios o parámetros de configuración que nos permitan entendernos con un servidor de
correo local, bien para enviar y recibir correos a usuarios de la misma máquina o red, o incluso
hacer relay a un proveedor como gmail, de manera que podamos enviar mensajes al exterior a través
de una cuenta de correos existente en un proveedor externo.
En un sistema de correo Linux totalmente funcional, probablemente se incluyan otros software. Lo
normal es tener un servidor de correo saliente (push) y uno de correo entrante (pull), además de
utilidades que nos ayuden a reorganizar el correo, a filtrarlo, a detener correo spam, etc…
Existen diferentes alternativas para servidores de correos de tipo push. Algunos de estos con formatos
de configuración mas complejos, mientras que otros quizás estén mas orientado a proporcionar
seguridad, o una configuración rápida y efectiva. Los servidores de correo mas populares en Linux son:
•Sendmail: Durante muchos años fue el servidor de correo dominante en Internet. Es muy
potente pero también difícil de configurar. Sus archivos de configuración pueden parecernos algo
arcaicos.

•Postfix: Diseñado como sustituto modular de sendmail ya que utiliza varios programas,
controlando cada cual su pequeña tarea específica. Esto lo hace mas seguro y además suele ser
mas fácil de configurar que sendmail. Es el servidor de correo por defecto en muchas
distribuciones Linux. Será este el que usemos en los ejemplos de configuración que veremos en
breves.

•Exim: Al igual que sendmail, es un servidor monolítico pero su formato de configuración es mas
sencillo por lo tanto mas fácil de configurar. Algunas distribuciones de Linux lo emplean como
servidor de correo por defecto.
•qmail: Es un servidor modular (como postfix) con la seguridad como principal objetivo. Es mas
sencillo de configurar que sendmail, pero debido a su licencia, la cual complica su distribución
en Linux, no se ofrece como servidor de correo por defecto.

Podemos averiguar de diferentes formas que servidor de correo instala nuestra distribución por defecto
como por ejemplo mediante el comando ps o incluso mirando dentro de los
directorios /usr/bin o /usr/sbin. Para ambos podemos aplicar filtros con grep como ya vimos en
Capítulos anteriores. Por motivos de compatibilidad la mayoría de servidores de correo Linux incluyen
un programa sendmail, por lo que este podría servir de patrón en nuestra búsqueda.
De igual modo que con el servidor push, dependiendo del modo en el que vayamos a configurar
nuestra forma de recibir correos podremos optar por algunas opciones entre las que destacamos:
•Servidores pull de correo: Los dos protocolos mas populares para este tipo de sistema
son POP e IMAP y ya vimos la diferencia básica entre ellos. Algunas de las herramientas mas
destacadas con las que podremos controlar la lectura del correo en
nuestro Linux son: cyrus, dovecot y courier (los tres tienen su equivalente tanto
para POP como IMAP).

•Fetchmail: Si dependemos de un ISP externo para la distribución de correo, necesitaremos un


programa que obtenga el correo utilizando POP o IMAP, y que después lo inserte en una cola de
correo SMTP. Esta es la función principal de Fetchmail.

•Lectores de correos: Son el último eslabón de la cadena de correo. Existen muchos y suelen
venir incluidos con la aplicación cliente. Por nombrar
algunos: Evolution, KMail, Thunderbird o mutt. Mientra los tres primeros son
para GUI, mutt puede ser útil para leer el correo desde la línea de comando, posee una interfaz
gráfica para la shell, es decir está basado en texto.

Alguna de las herramientas de las que podemos hacer uso para completar nuestro sistema de correos
podrían ser:
•d-push: Útil si queremos recuperar mediante push el correo en dispositivos móviles. Requiere
de un servidor web como apache o nginx y de soporte para PHP.

•procmail: Funciona como MDA (Mail Delivery Agent, Agente de entrega de correo). Sirve para
filtrar y clasificar el correo de entrada. Permite a los usuarios definir reglas que filtren
los email recibidos y realizar una serie de funciones como colocarlos en determinadas carpetas,
clasificarlos, reenviarlos, etc…

•spamassassin: Identifica el correo sospechoso o masivo añadiendo cabeceras a los mensajes


de modo que pueda ser filtrados por el cliente de correo electrónico

En las dos próximas secciones abarcaremos una configuración básica para en reenvío de correo
electrónico dentro de la red local o el propio sistema (algo que en muchas distribuciones viene por
defecto) y como reenviar el correo a un proveedor externo. No vamos a abarcar la configuración de un
servidor de correo totalmente funciona pues son muchas y diferentes configuraciones las que entran
en juegos, pero para que quede una idea, podremos montar una infraestructura con:
•Postfix quién hará de servidor SMTP enviando y recibiendo el correo

•dovecot para recuperar el correo IMAP en aplicaciones clientes de los usuarios

•spamassassin para controlar el spam

•procmail para filtrar y clasificar el correo

•d-push con el que recuperar los email en clientes móviles


Configuración básica local
Ahora que tenemos claro los conceptos vamos a proceder a configurar un servidor de correo de
manera que el sistema pueda enviar y recibir email entre cuentas de usuarios, algo que en muchos
sistemas viene configurado por defecto. Para ello vamos a usar Postfix como SMTP sobre la
distribución Linux Mint 17.1 (derivado de Debian)
Nota: En distribuciones como CentOS o Fedora (derivados de Red Hat) este sistema viene ya
preconfigurado para un funcionamiento a nivel local.
En caso de que ya tuviéramos postfix instalado (de lo contrario deberemos de buscarlo por ejemplo
con aptitude search postfix, en caso de distribuciones derivadas de Debian, y posteriormente instalarlo
con apt-get) pero no configurado haremos:

$ sudo dpkg-reconfigure postfix

Esto volverá a ejecutar el programa de configuración posterior a la instalación de postfix. En el se


realizan una serie de preguntas a las que deberemos de responder y con estos datos se creará el
archivo de configuración /etc/postfix/main.cf que en caso de tenerlo podemos ahorrarnos el pasar por
esta interfaz de menú y editar el archivo directamente. Importante recargar el servicio tras su edición.
Otra manera de efectuar cambios sobre main.cf es a través de la herramienta postconf (herramienta
de configuración de postfix) la cual además también nos sirve para ver el valor de los parámetros de
configuración o modificarlos. Por ejemplo, para ver el valor de una directiva de main.cf bastará con
pasársela como argumento a postconf, Si queremos cambiarle su valor, lo haremos así ‘postconf -
e <directiva=valor>‘. Si queremos ver el valor que trae por defecto cada directiva de main.cf bastará
con pasarle el parámetro -d, o -n para listar todas aquellas que tenemos ya configuradas. Con -p
listaremos todas las directivas de configuración de postfix, tanto aquellas a las que no se les ha
cambiado su valor como las que si se han modificado. Sobre-escribiremos el valor de una directiva
usando -o como opción. Existe otro archivo igual de importante (o incluso mas) que configura el
servidor postfix y es master.cf. Para mostrar su contenido usaremos -M,
Las preguntas a contestar (y sus respuestas para mi configuración personal básica) son:
•Configuración base inicial: solo correo local

•FQDN: En mi caso no dispongo de dominio así que ‘freeser‘ a secas será el nombre de mi host.

•Alias para redireccionar el correo de postmaster y root: Yo lo redirecciono todo a mi usuario


‘nebul4ck‘

•Lista de dominios separados por comas para los que actuará nuestro servidor: <ok>. Yo la dejo
tal cual, básicamente con el nombre de mi host y si tuviese dominio pues lo pondría igualmente.

•Sincronizar el correo de forma síncrona: <No>. Esto ralentiza el procesado del servicio de
correo. Si tenemos un sistema de archivos con journal no tiene por que hacernos falta.

•Configuración del bloque de red: Para enviar y recibir en equipos de la red sería algo parecido
a 192.168.1.0/24 (podemos eliminar la IP IPv6 si no la vamos a utilizar). Yo dejo la que viene por
defecto que es para gestionar solo el correo local (127.0.0.1/8)

•Tamaño máximo del buzón de correo: 0 ilimitado, 51200000 el valor dado por el desarrollador.
Esto no tiene que ver con la cuota de correo para cada usuario, para eso deberemos de usar el
sistema de Quota Disk que ya hemos estudiado.

•Elegir un caracter que defina la extensión de dirección local: ‘+‘ por defecto. Yo lo dejo en
blanco.
•Concretar el protocolo de IP a utilizar: IPv4 en mi caso

Estas preguntas y respuestas lo que hacen es añadir/modificar las siguientes líneas del
archivo main.cf, con las que tendremos un sistema igualmente funcional en caso de que queramos
hacerlo editando el archivo directamente:

relayhost =
myhostname = freeser
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = nombredetuequipo
mynetworks = 127.0.0.1/8
mailbox_size_limit = 51200000
inet_interfaces = loopback-only
inet_protocols = ipv4

Una vez tenemos la configuración base para postfix vamos a crear un alias para root, recordar que en
los pasos anteriores creamos un alias para nuestro usuario de manera que todo el correo
de postmaster y root se redirigiera a nuestro usuario, pero al parecer, según el mensaje obtenido tras
la configuración: WARNING: /etc/aliases exists, but does not have a root alias. root no tiene alias
por lo que deberemos de redirigir todo el correo (incluido el de postmaster) hacia root y entonces el
de root será redirigido a nosotros. Para ello editamos el archivo /etc/aliases. Bastará con escribir ‘root:
nuestrousuario‘
Nota: En la sección “Administrando el correo electrónico” veremos como crear alias y redirigir el
correo.
Ahora con el archivo /etc/aliases editado, necesitaremos ejecutar el comando newaliases para crear
un binario que pueda ser leído por el sistema.
Con esta configuración ya podremos enviar correos entre los usuarios del sistema local o red si hemos
configurado el bloque de red de la siguiente manera:

$ mail -s "Asunto" usuariodelsistema@nombredehost

Nota: Si el prompt devolviera el típico “mail: command not found” deberemos de instalar el
paquete mailutils que es donde suele encontrarse la utilidad mail.
Tras introducir esta línea nos aparece ‘cc:‘ esto es por si queremos poner en copia a alguien, si no
queremos pulsamos <Enter> y a continuación el prompt esperará que introduzcamos texto. Una vez
terminado pulsamos Control+D y el email será enviado.
En la sección “Administrando el correo” veremos mas opciones de mail y aprenderemos a gestionar
nuestro correo.

Configuración para reenviar correo a un proveedor como gmail


En la sección anterior hemos aprendido a configurar postfix para enviar correo desde una cuenta de
nuestro sistema a otra cuenta del mismo sistema u otro dentro de nuestra red local. Lo que haremos
ahora será configurar un relay en postfix de manera que podamos reenviar el correo desde nuestra
cuenta del sistema a una cuenta propia en un servidor de correo externo como podría ser gmail (para
nuestro ejemplo) y que sea esta la que envíe el correo al destinatario. Así podremos salir a Internet
fácilmente a través de un proveedor externo.
Para pasar de la configuración de correo local a hacer relay contra por ejemplo gmail las líneas a tener
en cuenta y que deberíamos de agregar en caso de no existir en main.cf serían las siguientes:
•relayhost = [smtp.gmail.com]:587

•smtp_sasl_auth_enable = yes

•smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

•smtp_sasl_security_options = noanonymous

•smtp_tls_CAfile = /etc/postfix/cacert.pem

•default_transport = smtp

•relay_transport = relay

Las modificaciones han sido claras. Estamos indicando que queremos hacer relay contra el
servidor SMTP de gmail por el puerto 587, hemos habilitado el mecanismo de
autenticación sasl indicando que archivo es el que contiene las credenciales de la cuenta que vamos a
usar para hacer el relay con la opción ‘noanonymous‘, se ha referenciado el PATH para el certificado
de nuestra máquina y por último se han modificado las directivas default_transpor y relay_transport,
ambas con el valor ‘error‘ en nuestra anterior configuración “solo correo local“.
Por lo general suelen existir las siguientes líneas en main.cf, de lo contrario (como por ejemplo
en CentOS y Fedora) deberemos de añadirla nosotros para habilitar la capa SSL/TLS:
•smtpd_use_tls = yes

•smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

•smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

•smtp_tls_policy_maps = hash:/etc/postfix/tls_policy

Volviendo a las líneas anteriores, para crear el archivo de credenciales ‘sasl_passwd‘ y hacer
que postfix lo reconozca haremos lo siguiente:
1. Crear el archivo con las credenciales:

$ sudo vi /etc/postfix/sasl_passw

2. Añadimos la línea a sasl_passw con los datos de la cuenta:

[smtp.gmail.com]:587 [email protected]:PASSWORD

3. Cambiamos el modo de acceso del archivo a solo lectura para root:

$ sudo chmod 400 /etc/postfix/sasl_passwd

4. Indicamos a postfix que utilice el archivo de credenciales:

$ sudo postmap /etc/postfix/sasl_passwd

Con el archivo de credenciales creado y reconocido por postfix, pasamos a generar un certificado.
En Linux Mint contamos con bastantes certificados preinstalados. En concreto nosotros usaremos uno
de los que son válidos para gmail ‘Thawte_Premium_Server_CA.pm‘:

$ ls -lt /etc/ssl/certs |grep Thawte


Thawte_Premium_Server_CA.pem ->
/usr/share/ca-certificates/mozilla/Thawte_Premium_Server_CA.crt

Por lo que podremos generarlo de la siguiente manera:

$ cat /etc/ssl/certs/Thawte_Premium_Server_CA.pem | sudo tee -a


/etc/postfix/cacert.pem

Importante: Igualmente podríamos haber creado nuestro propio certificado, algo que no será útil por
ejemplo en CentOS (entre otras) donde no contamos con estos certificados preinstalados. Para crear
nuestro propio certificado haremos:

# cd /etc/pki/tls/certs

# make <nombre_host>.pem

Se nos hará una serie de preguntas a las que deberemos de responder, como el País,
la Ciudad o Estado, email, etc… luego ya podremos generar nuestro certificado:

# cp /etc/pki/tls/certs/<nombre_host>.pem /etc/postfix/cacert.pem

Nota: Si hemos tenido que crear nuestro propio certificado normalmente en estas distribuciones
tendremos que crear un archivo /etc/postfix/tls_policy y seguir los mismos pasos realizados con el
archivo /etc/postfix/sasl_passwd solo que el contenido a añadir será:
[smtp.gmail.com]:587 encrypt
Ahora, como ya sabemos, cada vez que modificamos main.cf toca recargar el archivo de configuración
o incluso reiniciar el servicio, así que:

$ sudo service postfix reload | restart

Hasta aquí debe de estar todo listo para poder hacer el reenvío. Antes comentamos alguna forma de
enviar un correo desde la línea de comandos con mail, aquí mostramos esta otra:

$ echo "Este es mi tercer email" | mail -s "Mi tercer" [email protected]

Para ver lo que ha ocurrido como siempre visitaremos nuestro mejor amigo /var/log/mail.log o /var/log/
maillog
Podremos encontrar mucha información sobre como configurar el
servidor postfix en /usr/share/doc/postfix/
Los servidores de correo proporcionan una amplia variedad de opciones avanzadas para priorizar el
envío de correos, aceptar mensajes por la línea de comandos, borrar mensajes específicos de la cola,
depurar conexiones de correos y otras muchas opciones que no se han abarcado en esta sección por
no extender en demasía el Capítulo, además de no ser el propósito de esta guía de estudios para
LPIC-1.

Proteger el servidor
En esta sección no se desarrollarán métodos sobre como securizar nuestro servidor de correos, pero si
alguna información importante a tener en cuenta y herramientas que pueden hacernos la vida menos
complicada en lo referente a nuestro servidor de correos. Por ejemplo algo con lo que estar
familiarizado deben de ser los bugs del propio servidor de correos o herramientas que usemos para
dar de alguna forma asistencia o complementación a nuestro servicio de correo. Los bugs pueden
poner en peligro el sistema permitiendo a alguien obtener acceso y enviar correos, o como vimos en el
Capítulo anterior sobre el diagnóstico de la red, conectándose al puerto 25 (SMTP) mediante un
cliente Telnet y escribiendo comandos SMTP para aprovechar la vulnerabilidad. Es por esto que
muchas distribuciones de Linux reducen el acceso exclusivamente al ordenador local. Es muy
importante instalar los parches que puedan surgir a raíz de bugs encontrados y actualizar el sistema
constantemente.
Otro aspecto a tener en cuenta es la configuración. Deberemos de ser conocedores de que parámetros
son los que estamos configurando y que valor le estamos dando. Existen configuraciones defectuosas
que permiten a spammers utilizar su servidor de correos para enviar email masivos por lo que no
tardarán en bloquear nuestra IP o añadirla a listas negras (blacklist). A este tipo de configuraciones se
las llama open relay (transmisiones abiertas). La mayoría de distribuciones Linux configuran el
servidor de manera que no permita el open relay por lo que de cierta manera podemos andar
tranquilos. No obstante deberemos de revisar de que nosotros tenemos la configuración apropiada.
Existen varias maneras o sitios en Internet en los que podremos comprobar esto como por ejemplo
desde la web http://www.spamhelp.org/shopenrelay, o bien mediante conexión Telnet, conectando a
nuestro servidor SMTP por su IP y puerto 25 y enviando comandos SMTP.
Algunas herramientas útiles de cara a la seguridad en sistemas totalmente funcionales de correo
electrónico pueden ser: spamassassin (herramienta open source que utiliza una extensa serie de test
o reglas tanto a nivel local como de red para identificar firmas de spam en los correos
electrónicos.), smapd o greylist (ambas orientadas a reducir el correo spam).

Administrar el correo electrónico


Hasta aquí hemos visto algunos aspectos básicos sobre la configuración de un servidor postfix SMTP,
de manera que podamos enviar y recibir correos en nuestra máquina local o aquellas que pertenecen a
nuestra red, y además como reenviar correo desde nuestra cuenta del sistema hacia una cuenta en un
proveedor externo (en nuestro caso gmail) para que sea esta quien entregue el correo del sistema a
través de Internet. En las siguientes secciones aprenderemos un uso básico sobre la administración
del correo de manera local, como el envío y lectura del correo a través de la línea de comandos, ver la
cola de correo y eliminar alguno o todos los correos existente en ella, además de como redirigir el
correo entre usuarios de una máquina mediante aliasde correo.

Enviar y recibir correo desde la línea de comandos


Linux dispone de una amplia gama de aplicaciones de correo cliente o MUA (Mail User Agent) con las
que poder administrar una cuenta. Alguna de estas pudiesen ser Geary, sistema cliente básico para
principiantes, Thunderbird, Evolution y KMail, todas ellas disponibles para GUI y orientadas a
usuarios mas avanzados, Zimbra, para acceder vía web. Además Zimbra es un paquete Open
Source con el que podremos crear y gestionar un servidor funcional completo de correos
(SMTP, POP, IMAP…) que incluye otras funcionalidades como la Agenda y el Calendario. Otro cliente
con el que podremos enviar y recibir correo pero esta vez desde la línea de comandos
es mutt. Mutt es un MUA que soporta protocolos como IMAP y POP para la lectura del correo, así
como SMTP para la transferencia. Es bastante configurable y su interfaz está basada totalmente en
texto. No obstante en esta sección nos vamos a centrar en la ya mencionada herramienta mail con la
que podremos envía correo desde la línea de comandos e incluso leerlos.
La sintaxis básica de mail es la siguiente:

• Para enviar un correo:


mai [-v] [-s “asunto”] [-c “dirección con-copia” | -b “dirección con copia oculta”] dirección
destinatario
Nota: La opción -c no trabaja en todas las versiones de mail
Anteriormente ya vimos dos formas de enviar un email, bien escribiendo la línea del comando mail la
cual nos desplegará un prompt donde introducir texto y finalizar con Control+D o bien mediante el
comando echo redireccionado a mail. Otras dos formas de enviar un correo serían:
1. Enviar el contenido de un archivo como correo:

mail -s "Lista de invitados para la fiesta!!" <


/home/party/listainvitados.txt [email protected]

2. Es igual a la opción básica pero en vez de usar Control+D para finalizar, utilizamos una palabra:

mail -s "Tareas por hacer" [email protected] << EOF


Aqui escribiremos todo lo que queramos
El correo terminará cuando repitamos la palabra con
la que abrimos el contenido de este email
EOF

Nota: Esta última forma es muy útil en correos enviados desde shell scripts.
•Para leer un correo:

mail [-v] [-f “/var/mail/<usuario>” | -u <usuario>]


Con -f indicaremos el nombre del archivo de correo de un determinado usuario o bien con -u pasamos
directamente el nombre de ese usuario. Otras formas de leer el correo es desplegando el contenido del
archivo de correo de un usuario mediante un paginador de archivo o cat, o bien utilizando mailde forma
interactiva lo cual conseguiremos llamando a mail sin parámetros.
Cuando usamos mail de forma interactiva lo que hace es desplegar una serie de líneas de resúmenes
de mensajes (un resumen de mensaje por línea) con el siguiente formato:
<nº de mensaje> <remitente> <fecha> <nº de líneas>/<nº de bytes> <Asunto>
Deberemos de prestar atención al número de mensaje pues es el que deberemos de introducir para
desplegar su contenido. Posteriormente podremos eliminar el mensaje con d o responder a este con r.

Comprobar la cola de correo


El programa mailq es la principal herramienta para administrar la cola de correo. Originalmente este
programa formaba parte del paquete sendmail, es por ello que usar sendmail -bp es equivalente
a mailq. El comando básico (sin opciones) muestra el contenido de la cola de correo de todos los
sistemas.
Podremos vaciar una cola de correos con sendmail -q, postqueue (postfix) o runq (exim). Además
en postfix contamos con la utilidad postsuper con la que podremos eliminar toda la cola de correos
con ‘-d ALL’ o un solo correo con ‘-d <nº de correo>‘

Redirigir el correo
Por regla general los servidores de correo mantienen una cuenta propietaria que en la mayoría de los
casos se nombra postmaster a la que se le es enviado el correo y cuyo contenido solo debería de ser
leído por el administrador del sistema (root). Existe una manera con la que el correo es direccionado o
redirigido a otro usuario con el fin de que este pueda leerlo. Para hacer posible esto se cuenta con el
archivo aliases que suele encontrarse bajo /etc/ o bajo /etc/mail y que posee un formato sencillo pero
eficaz.
Si abriésemos este archivo veríamos una lista de líneas con un formato parecido al siguiente:

# Basic system aliases -- these MUST be present.


mailer-daemon: postmaster
postmaster: root

# General redirections for pseudo accounts.


bin: root
daemon: root
adm: root
...

Este sería el caso mas simple en el que se nombra a postmaster como mailer-daemon y seguidamente
se crea el primer alias en el que el correo de postmaster será redirigido a root (postmaster: root). Las
siguientes líneas (y algunas mas que faltan) por lo general lo que hacen es que el correo enviado a las
cuentas de servicios o programas del sistema sea redirigido a root, de manera que el administrador
cuente con la información de todos ellos. Al final de de este archivo podríamos añadir la siguiente
línea:

root: nuestrousuario

con lo que estaríamos diciendo que una vez que todo el correo del sistema (servicios y programas)
haya sido enviado a root, este sea su vez reenviado a nuestro usuario, con el fin de mantener un
control de esta información sin llegar a ser superusuario o poseer los permisos de este.
Además de usar un nombre de usuario del sistema al que redirigir el correo, podremos utilizar un
comando por el que canalizar los mensajes ( | ), el nombre de un archivo en el que se encuentran
añadidos una serie de direcciones o incluso una cuenta de correo como [email protected].
En la mayoría de servidores de correos es un requisito el compilar /etc/aliases a un archivo binario de
manera que pueda ser procesado mas rápidamente. Para esto usaremos el comando ya
visto newaliases
Otra manera de redirigir el correo es hacerlo a nivel de usuario, es decir, editando el
archivo ~/.forward del directorio principal del usuario de manera que el correo que es enviado a este,
sea reenviado a otra cuenta. Para hacer esto basta con editar el archivo con tan solamente el nombre
de usuario al que queremos redirigir el correo o bien una cuenta de correo electrónico completa. Este
sistema tiene varias ventajas como por ejemplo, el administrador del sistema podría crear por ejemplo
una cuenta ‘correos‘ y avisar a todos los usuarios del sistema que hagan el reenvío de su correo a esta
cuenta, de forma que el administrador pueda tener el correo de los usuarios de una forma controlada, o
bien los usuarios podrán reenviar el correo de varias de sus cuentas a una sola cuenta de usuario o
correo sin tener que molestar al administrador.

Administrar datos con SQL


En las siguientes secciones hablaremos sobre el Lenguaje de consulta estructurado o SQL (Structured
Query Languaje) que como su nombre indica es utilizado para obtener datos de una base de datos.
Para comenzar a utilizar SQL deberemos de disponer de algún paquete de software que lo
implemente. En Linux disponemos de algunos, siendo los mas habituales:
•MySQL: Este paquete nos ofrece un servidor de BBDD, un cliente para conectar con estas y
herramientas de desarrollo. Es un software en propiedad de Oracle el cual se distribuye
bajo GPL. La mayoría de las distribuciones de Linux incluyen a MySQL en sus repositorios
oficiales.

•PostgreSQL: Disponible bajo licencia BSD y es una evolución del software Ingres inicial. El
nombre de PostgreSQL es la compresión de Post-Ingres SQL. Al igual que MySQL, se encuentra
disponible en los repositorios oficiales de las distribuciones Linux.

•SQLite: Es una biblioteca que implementa SQL. No se trata de un gestor


de BBDD independiente, mas bien un procedimiento o medio que permite a un programa
almacenar datos utilizando una interfaz SQL del propio programa. Si desea escribir un programa
que acceda a BBDD pero instalar un software pesado como MySQL o PostgreSQL resulta
excesivo, quizás SQLite sea su solución.

Fundamentos de SQL
Desde LPI.org se está planteando la posibilidad de prescindir del contenido sobre gestión de bases de
datos y mas concretamente de la herramienta SQLcon la que acceder a BBDD relacionales. Es por ello
que nos hemos extendido un poco mas en el software del correo electrónico y lo haremos de forma
mas breve con respecto a SQL.
SQL permite la gestión de varias BBDD, a su vez estás están formadas por una o mas tablas
construidas por filas (tuplas) y columnas (atributos o campos).
Las columnas de una base de datos contienen tipos de datos específicos, ya que no es lo mismo
indicar un color (rojo) que un precio (1.99€). Usaremos los tipos de datos específicos para crear
restricciones relacionadas, llamadas “dominio” o “tipo de datos“.
Algunos de estos tipos de datos son:
•INTEGER (INT): Valor entero de cuatro bytes.

•SMALLINT: Valor entero de dos bytes

•DECIMAL o NUMERIC: Almacenamiento preciso de valores decimales

•FLOAT: Número de coma flotante

•DOUBLE PRECISION: Número de coma flotante almacenado con el doble de precisión que con
el que lo hace FLOAT

•DATETIME: Una fecha y una hora

•DATE: Una fecha

•TIME: Una hora en formato HH:MM:SS

•CHAR: Uno o mas caracteres

•VARCHAR: Un número variable de caracteres

•ENUM: Una lista enumerada de datos como pequeño, mediano y grande

•SET: Datos que pueden tener cero o más valores. Como para un yogurt de
macedonia: fresa, plátano, melocotón y pera.
Los datos de una tabla no están ordenados, pero podremos devolver el contenido de una consulta
realizada con SQL de forma ordenada y filtrada como veremos en breves.

Primeros pasos en una base de datos


Lo primero que debemos de hacer para aprender a utilizar SQL es tener acceso a una base de
datos SQL. Nosotros en nuestro ejemplo vamos a utilizar el motor MySQL. Aquí vamos a suponer que
tenemos ya instalado el paquete mysql en el que se incluye servidor, cliente y herramientas, y además
lo tenemos en ejecución (esto se hace de la misma forma que el resto de servicios Linux).
Para iniciar el cliente mysql basta con llamar a mysql sin parámetro alguno. Esto nos introducirá en
un prompt (mysql> ) que al igual que bash esperará a que introduzcamos comandos. Los
comandos SQL se suelen escribir en mayúsculas. No es obligación pero si una forma de simplificar o
clarificar la lectura de los comandos que normalmente ocupan mas de una línea. Una vez en
el prompt de mysql lo primero que debemos de hacer es mostrar las bases de datos existentes. Lo
normal es que no haya ninguna creada, pero mysql muy amigo nuestro nos tiene una preparada
llamada test con la que podremos iniciarnos.

mysql> SHOW DATABASES;

Es importante fijarnos en como terminamos la línea de comandos. El caracter punto y coma ‘ ;‘ es el


que indica que hemos terminado la línea de comandos, por lo que mientras que este no sea indicado
se entenderá que la línea de consulta sigue abierta.
Si queremos crear una base de datos utilizaremos el comando CREATE DATABASE seguido por el
nombre de la base de datos:

mysql> CREATE DATABASE animales;

Ahora podremos empezar a usar la tabla con el comando USE:

mysql> USE animales;

Como acabamos de crear la base de datos no existe ninguna tabla. Por ello vamos a crear una
tabla con cuatro columnas o campos que servirán para diferenciar unas filas o tuplas de otras que
iremos almacenando posteriormente. Por ejemplo:

mysql> CREATE TABLE gatos (nombre VARCHAR(30), raza VARCHAR(20), fech_nac


DATE, precio DECIMAL (4,2));

Con este comando crearemos la tabla ‘gatos‘ como hemos dicho de cuatro campos | id | nombre |
raza | fecha de nacimiento | precio |, en la que los dos primeros campos usan un tipo de datos de
caracter variable, es decir podrán tener un máximo de 30 y 20 caracteres respectivamente. Si
hubiésemos utilizado CHAR tanto los nombres de los gatos como sus razas deberían de tener
exactamente 30 y 20 caracteres respectivamente. Para la fecha de nacimiento usamos el tipo DATE y
algo a tener en cuenta en el campo ‘precio‘ es que podríamos haber usado el tipo FLOAT pero sin
duda para un campo en el que vamos a definir algo tan importante y exacto como es un precio, es
preferible utilizar el tipo DECIMAL (mas exacto que FLOAT) con el que se indica los dígitos que irán
delante de la coma (4 en este caso) y cuantos decimales tras la coma (2 para nuestro ejemplo). En
otros motores de bases de datos existe el tipo MONEY pero MySQL no lo soporta.
Antes de pasar a almacenar datos en la tabla vamos a ver como mostrar las tablas que forma la base
de datos:

mysql> SHOW TABLES;

Una vez localizada que tablas forman una base de datos podremos ver los campos que construyen
a cada tabla. Vamos a ver por ejemplo que campos (nombre, raza, fecha de nacimiento y precio en
nuestro ejemplo) son la base de la tabla gatos.

mysql> DESCRIBE gatos;

Bueno ahora que hemos localizado nuestra base de datos, hemos creado una tabla y hemos
mostrado que campos son los que finalmente hemos añadido, vamos a pasar a almacenar
información dentro de estos. Para insertar una tupla en una tabla usaremos el comando INSERT
INTO de la siguiente manera:

mysql> INSERT INTO gatos


-> values ('rigodón', 'europeo', '2009-02-28', 23,4);

Bueno ahora supongamos que hemos insertado un dato erróneo, por lo que vamos a actualizar los
datos de la tabla con el valor correcto:

mysql> UPDATE gatos SET precio=12.99 WHERE nombre='rigodon';

Esto buscará la tupla que tiene como nombre rigodon y volverá a setear el valor de precio pero esta
vez con el valor 12.99. Si existiesen mas de una tuplacon nombre rigodon deberemos de añadir mas
criterios de filtrado. Podemos conseguir esto con AND y OR. Por ejemplo, vamos a suponer que
existen dos filas con el valor rigodon en el campo nombre pero solo una con la fecha de
nacimiento 2009-02-28, para localizar esta tupla usaremos la siguiente línea:

mysql> UPDATE gatos SET precio=12.99 WHERE nombre='rigodon' AND


fech_nac='2009-02-28';

Como últimos comandos a estudiar en esta sección y no por ello menos importantes son DELETE
y DROP con los que podremos eliminar algunos o todos los datos de una tabla o eliminar la tabla
competa respectivamente.
Si queremos eliminar todos los datos de una tabla haremos uso del comodín ‘*‘:

mysql> DELETE * FROM gatos;

Podemos eliminar solo datos específicos así:

mysql> DELETE FROM gatos


-> WHERE raza='persa' OR precio > 21,99;

Nota: Esto eliminará toda las tuplas pertenecientes a gatos cuya raza es ‘persa‘ o tienen un precio
superior a 21,99
En ocasiones lo que querremos será borrar una tabla completa (tuplas y campos) ya porque esta no
sirva o porque haya tantos datos erróneos o desfasados que ya no nos interesen. En este caso
usaremos DROP de la siguiente manera:
mysq> DROP TABLE gatos;

Entre las numerosas posibilidades de manipulación de datos con las que cuenta SQL tenemos la de
recuperar datos de distintas tablas y combinarlos, dando como salida una única tabla con los datos
necesitados. Para lograr esto, las tablas a combinar deben de tener todas ellas un campo común que
pueda ser utilizado para conectarlas y además cada tabla igualmente deberá de tener un campo cuyo
valor identifique inequívocamente a cada tupla. A este campo se le llama PK (Primary Key, Clave
Primaria).
Antes de nada debemos de conocer el comando SELECT. SELECT nos permite realizar consultas en
una base de datos. Será el comando que nos ofrezca la posibilidad de recuperar los datos de las
distintas tablas para posteriormente manipularlos o simplemente obtener la información deseada.
La sintaxis básica para SELECT es la siguiente:
SELECT campo(s) FROM tabla [ WHERE condiciones ] [ ORDER BY campo ]
Vamos a recuperar todos los datos de la tabla gatos:

mysql> SELECT * FROM gatos;

Podemos seleccionar uno o varios campos de la siguiente manera:

mysql> SELECT nombre, raza FROM gatos;

Y de la misma manera que ya hemos visto podemos filtrar la consulta con WHERE y ser mas
específicos con AND, OR o NOT:

mysql> SELECT * FROM gatos WHERE raza='persa' OR fech_nac>'2008-11-29' AND


NOT raza='europeo';

Podemos incluso ordenar la salida por un campo en orden ascendente (ASC) o descendente (DESC).
Igualmente podemos sumar (SUM) todos los valores de un campo. Esto último es útil por ejemplo si
queremos sumar el precio de todas las mascotas.

mysql> SELECT raza,precio FROM gatos WHERE precio>15.99 GROUP BY precio ASC

Una vez que conocemos el uso básico de SELECT será suficiente para poder combinar la salida de
por ejemplo dos tablas. Para combinar tablas podemos usar el mismo comando SELECT aunque se
suele emplear JOIN. A continuación veremos un ejemplo, pero antes vamos a hacer un uso sencillo de
otro de los comandos que nos ofrece SQL y es ALTER TABLE. Este comando nos permite modificar la
estructura de una tabla ya existente, por ejemplo, añadir nuevas columnas o eliminar otras o bien,
crear y borrar restricciones. Para ello se permite el uso de palabras reservadas como ADD(añade o
modifica una columna), DROP (elimina una columna o restricciones sobre ella), UNIQUE (los datos de
cada tupla de la columna serán únicos),PRIMARY KEY (esta columna hará de clave primaria para
cada tupla) y CONSTRAINT (añade o elimina una restricción) . ¿ Porque comentamos esto aquí ? –
pues porque si hubiésemos seguido los ejemplos que hemos ido realizando, nos daríamos cuenta (en
caso de que no hayamos eliminado ya la tabla o base de datos) que cuando creamos la tabla gatos no
creamos el campo/columna ‘id’ el cual nos permitirá combinar tablas con SELECT o JOIN. La sintaxis
de ALTER es la siguiente:
•Añadir una columna (para eliminarla usamos la misma sentencia pero
cambiamos ADD por DROP):

ALTER TABLE <tabla> ADD [COLUMN] <nombre_columna> <tipo>


•Añadir una columna con restricciones:

ALTER TABLE <tabla> ADD [COLUMN] <nom_column> <tipo> RESTRICCIONES


•Añadir restricciones a una columna ya existente:

ALTER TABLE <tabla> ADD [COLUMN] RESTRICCIONES <columna>


Nota: Para eliminar una restricción usamos la sintaxis anterior pero cambiamos ADD por DROP
Antes de pasar al ejemplo que comentábamos sobre la combinación de tablas
con SELECT y JOIN vamos a crear definitivamente nuestro campo id en la tabla gatos con las
siguientes restricciones: el campo no podra ser nulo (NOT NULL) y nos valdrá como clave primaria
(PRIMARY KEY). Será de tipo entero y con un máximo de cuatro dígitos de longitud:

mysql> ALTER TABLE gatos ADD COLUMN id INTEGER(4) NOT NULL PRIMARY KEY;

Aviso: El ejemplo anterior solo ha servidor para mostrar como crear una columna con un nombre y tipo
y dos restricciones pero en la práctica obtendremos un error diciendo que no podemos hacer el campo
id PK. Esto es porque al ser NOT NULL se le ha asignado el valor 0 a todos y al ser repetido es
imposible que sea una clave primaria. Por ello anularemos el PRIMARY KEY, le daremos un valor
diferente a cada tupla y a continuación usaremos la siguiente sentencia:

mysq> ALTER TABLE gatos ADD PRIMARY KEY (id);

Ahora que ya tenemos nuestro campo id en la tabla gatos volvamos al ejemplo de combinación de
tablas:
Ejemplo: Un veterinario nos pide que saquemos los números de contacto de todos los gatos mayores
de cinco años que tienen implantado el chip de reconocimiento y que además estén vacunados.
Lo primero que haremos será localizar las tablas que tengan campos en común y posean el campo PK.
Además de esto las tablas deberán de tener la información de si se encuentran vacunados, si existe un
número de contacto y la fecha de nacimiento. Vamos a suponer que ya hemos dado con dos tablas
que nos serán útiles.
•La tabla gatos tiene los siguientes campos: id | nombre | raza | fech_nac | precio |

•La tabla identificación está formada por: num_chip | nombre | vacunado | contacto |

Sabemos que las PK de ambas tablas son ‘id‘ y ‘num_chip‘ y el campo común es ‘nombre‘. Para
obtener la información que nos ha pedido el veterinario haremos lo siguiente:

mysql> SELECT gatos.nombre, gatos.fech_nac, identificacion.vacunado,


identificacion.contacto
-> FROM gatos, identificacion
-> WHERE gatos.nombre=identificacion.nombre AND gatos.fech_nac<'2010-01-01'
AND identificacion.vacunado='si';

Si queremos combinar de la misma forma pero usando JOIN solo existe la diferencia de que una tabla
es especificada con FROM y la otra con JOIN:

mysql> SELECT gatos.nombre, gatos.fech_nac, identificacion.vacunado,


identificacion.contacto
-> FROM gatos
-> JOIN identificacion
-> WHERE gatos.nombre=identificacion.nombre AND gatos.fech_nac<'2010-01-01'
AND identificacion.vacunado='si';

Y hasta aquí todo lo relacionado con la administración de bases de datos. Ha sido un mini tutorial pero
como ya indicamos al principio de la sección, este contenido puede quedar obsoleto con respecto a la
certificación LPI-1

También podría gustarte