20 trucos de seguridad para Apache

Estas son 20 recomendaciones para optimizar la seguridad en tu servidor Apache, del mismo modo debes tener en cuenta que algunas de estas recomendaciones pueden disminuir el rendimiento de tu servidor dependiendo de tu configuración y de las especificaciones del sistema.
Primero, cerciorarte de tener instalado los últimos parches de seguridad

No tiene sentido poner una cerradura mas resistente a tu puerta si dejas la ventana abierta. Del mismo modo si no tenemos los últimos parches de seguridad instalado no tendría sentido continuar con la optimización de seguridad.

Restringir acceso por IP

Si tienes un recurso al que deba solamente tener acceso alguna red, o IP en concreto puedes configurarlo en Apache. Por ejemplo si deseas restringir el acceso a tu Intranet para permitir solamente la red 176.16:


Order Deny,Allow

Deny from all

Allow from 176.16.0.0/16

o por IP:

Order Deny,Allow

Deny from all

Allow from 127.0.0.1

Oculta la versión y otra información delicada

Por defecto muchas instalaciones de Apache muestran el número de versión que está funcionando, el sistema operativo y un informe de módulos de Apache están instalados en el servidor. Los usuario maliciosos pueden utilizar esta información para atacar tu servidor.

Hay dos directivas que necesitas agregar, o corregir en tu archivo de httpd.conf:

ServerSignature Off

ServerTokens Prod

El ServerSignature aparece en la parte inferior de las páginas generadas por apache tales como los famosos errores 404.

La directiva ServerTokens se utiliza para determinarse lo que pondrá Apache en la cabecera de la respuesta HTTP del servidor.

En Debian se encuentra en :»/etc/apache2/conf.d/security»

ServerTokens Prod

ServerSignature Off

TraceEnable Off

Apache debe funcionar bajo su propia cuenta y grupo de usuario Algunas versiones de Apache corren bajo el usuario nobody, esto compromete mucho su seguridad por lo tanto haz lo siguiente:

User apache

Group apache

Utiliza el mod_security

El mod_security es un módulo estupendo de Apache escrito por Ivan Ristic, el autor de Apache Security de O’Reilly.

Esta es una lista de cosas que puedes hacer con mod_security:

* Filtración simple

* Filtración basada en expresiónes regular

* Validación de codificación de la URL

* Validación de codificación Unicode

* Auditing

* Prevención del ataque NULL Byte

* Límitar la memoria de subida

* Enmascarar la identidad del servidor

* Y más

Deshabilitar cualquier módulo innecesario

Apache viene por defecto instalado con un serie de módulos.Debes echarle un vistazo a la documentación de Apache y ver para que sirve cada uno de ellos, y de esta manera te darás cuenta de que hay algunos que no son útiles en tu servidor.

Busca en httpd.conf las lineas que contengan LoadModule. Para deshabilitar el módulo debes agregar un # al principio de la línea, para que de esta forma pase a ser un comentario. Para buscar los módulos prueba con:

grep LoadModule httpd.conf

Aquí están algunos módulos que se instalan por defecto pero a menudo no son necesarios: mod_imap, mod_include, mod_info, mod_userdir, mod_status, mod_cgi, mod_autoindex.

Asegurarte de que los archivos a los que se accede son los deseados

No deseamos que se pueda acceder a los directorios que no tengan permisos para ello, supongamos que el directorio raíz para nuestras webs es /web, la configuración óptima deberá ser la siguiente:

Order Deny,Allow

Deny from all

Options None

AllowOverride None

Order Allow,Deny

Allow from all

Desactiva las opciones para explorar directorios

Esto lo puedes hacer con las opciones de directiva dentro de la etiqueta directorio tiene dos posibles valores none o indexes.

Options -Indexes

Desactiva los includes del lado servidor

Esto también se hace con las opciones de directiva dentro de la etiqueta directorio tiene dos posibles valores none o include.

Options -Includes

Desactiva la ejecución de CGI

Si no necesitas la ejecución de CGI por algún motivo en concreto desactivarlos se hace con las opciones de directiva dentro de la etiqueta directorio tiene dos posibles valores none o ExecCGI.



Options -ExecCGI

No permitir que apache siga enlaces simbólicos

De nuevo se configura con las opciones de directiva dentro de la etiqueta directorio tiene dos posibles valores none o FollowSymLinks.

Options -FollowSymLinks

Desactivar todas las opciones

Si deseas desactivar el uso de todas las opciones simplemente:

Options None

Si solamente deseas desactivar algunas en concreto, separarlas con un espacio en las opciones de directiva:

Options -ExecCGI -FollowSymLinks -Indexes

Desactivar la ayuda para los archivos .htaccess

Esto esta ya hecho pero con la directiva AllowOverride. Cámbialo a none.

AllowOverride None

Otra opción interesante sería bloquear la descarga de todos los archivos que comienzen con .ht por ejemplo, se haría de la siguiente manera:

AccessFileName .httpdoverride

Order allow,deny

Deny from all

Satisfy All

Disminuye el valor máximo de tiempo de espera

Por el defecto el tiempo de espera es de 300 segundos. Puedes disminuirlo por seguridad para prevenir ataques de esta manera:

Timeout 45

Limitar el tamaño máximo de peticiones

Apache tiene varias directivas que permiten que limites el tamaño de una petición, esto puede ser muy útil.

Una buena manera de comenzar es con la directiva LimitRequestBody. Esta directiva esta fijada a ilimitado por defecto. Si estás permitiendo uploads de archivos que no sean mayores a 1MB, podrías fijar este ajuste a algo parecido a esto:

LimitRequestBody 1048576

Si no estás permitiendo uploads de archivos puedes fijarlo incluso a un tamaño más pequeño.

Algunos otras directivas a mirar son LimitRequestFields, LimitRequestFieldSize y LimitRequestLine.

Sistema de archivos de red (NFS)

Un Sistema de archivos de red (NFS) permite a los hosts remotos montar sistemas de archivos sobre la red e interactuar con esos sistemas de archivos como si estuvieran montados localmente.

Todas las versiones de NFS pueden utilizar el Protocolo de control de transmisiones (TCP) ejecutándose sobre una red IP. En el caso de NFSv4, éste lo

requiere. NFSv2 y NFSv3 pueden utilizar el Protocolo de datagrama de usuarios
(UDP) sobre una red IP para proporcionar conexiones de red sin supervisión
(stateless) entre el cliente y el servidor.

Necesitaremos tener instalado portmap y el paquete nfs (nfs-utils) que se puede encontrar en la mayor de las distribuciones en el ordenador que vaya a hacer de servidor de disco.

El portmap nos permitirá realizar conexiones RPC al servidor y es el encargado de permitir o no el acceso al servidor a los equipos que especifiquemos.

Para saber si tenemos el portmap instalado bastar ́ con un simple

ps aux | grep portmap
Deberíamos tener una salida parecida a
rpc 1261 0.0 0.1 1560 568 ? S 15:48 0:00 portmap

Para saber si NFS está en marcha haremos una consulta al portmap para que nos indique que servicios tiene en marcha

rpcinfo -p
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 980 status
100024 1 tcp 983 status
100021 1 udp 24065 nlockmgr
100021 3 udp 24065 nlockmgr
100021 4 udp 24065 nlockmgr
100021 1 tcp 20789 nlockmgr
100021 3 tcp 20789 nlockmgr
100021 4 tcp 20789 nlockmgr
100011 1 udp 909 rquotad
100011 2 udp 909 rquotad
100011 1 tcp 912 rquotad
100011 2 tcp 912 rquotad
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100005 1 udp 922 mountd
100005 1 tcp 925 mountd
100005 2 udp 922 mountd
100005 2 tcp 925 mountd
100005 3 udp 922 mountd
100005 3 tcp 925 mountd

#portmap status

Si el servicio portmap se está ejecutando, entonces se puede iniciar nfs. Para

iniciar un servidor NFS, ejecutar:

#/etc/init.d/nfs-kernel-server start
Para detener el servidor, ejecutar:

#/etc/init.d/nfs-kernel-server stop

Configuraciones para el Servidor NFS

#/etc/hosts.deny
portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL

#/etc/hosts.allow
portmap:ip_cliente/mascara_cliente
lockcd:ip_cliente/mascara_cliente
mountd:ip_cliente/mascara_cliente
rquotad:ip_cliente/mascara_cliente
statd:ip_cliente/mascara_cliente

/etc/exports
/dir_compartir ip_cliente/mascara_cliente(rw,sync,no_root_squash)

En los clientes NFS

Montamos los directorios compartidos con NFS
en
#/etc/fstab
ip_servidor_NFS:/directorio_exportar /directorio_local nfs hard,bg,proto=tcp,suid,rsize=32768,wsize=32768,nointr,timeo=600 0 0

Donde:

hard o soft: Especifican si el programa que usa un archivo vía una conexión NFS, debe parar y esperar (hard) a que el servidor vuelva a estar en línea, si el host que sirve el sistema de archivos no está disponible, o si debe informar de un error (soft).

Si se especifica la opción hard, el usuario no podrá terminar el proceso que está

esperando que la comunicación NFS se reanude a menos que especifique la
opción intr.
Si usa soft, puede usar la opción adicional timeo=, donde especifica el número
de segundos que deben pasar antes de informar del error.

intr: Permite que se interrumpan las peticiones NFS si el servidor se cae o no
puede ser accedido.

rsize=num y wsize=num: Estas configuraciones pueden acelerar la configurando un tamaño de bloque de datos mayor, en bytes, que serán comunicación NFS tanto para lecturas (rsize) como para escrituras (wsize), transferidos de una sola vez. Tenga cuidado al cambiar estos valores; algunos kernels antiguos de Linux y tarjetas de red no funcionan bien con grandes tamaños de bloques. Para NFSv2 o NFSv3, los valores por defecto para ambos parámetros está configurado a 8192. Para NFSv4, los valores por defecto para ambos parámetros es 32768.

Iniciar la compartición de archivos
Si hemos cambiado el fichero /etc/exports después de iniciar el servicio NFS deberemos indicar al sistema que releea el fichero y active los cambios. Esto lo podemos hacer reiniciando el demonio nfsd o bien mediante

#exportfs -ra

Deshabilitar IPv6

Configuración para Centos y REHL 5.

En las distribuciones Linux basadas en Red Hat, los módulos son cargados usando
/etc/modprobe.conf.

Entonces para quitar el IPV6:

1.- Editamos este archivo «/etc/modprobe.conf» y agregamos lo siguiente:

alias net-pf-10 off
alias ipv6 off

2.- Editar el archivo de configuración de red:
pitache # vi /etc/sysconfig/network
Cambiar las siguientes opciones por NO:

NETWORKING_IPV6=no
IPV6INIT=no

3.- Apagar los Servicios de IPV6
pitache# service ip6tables stop

4. Para deshabilitar permanentemente ip6tables usando en comando chkconfig:
pi# chkconfig ip6tables off

5.- Reiniciar el servidor

6.- Verificar con ifconfig

Crear Repositorios Yellow dog Updater, Modified (YUM)

Introducción.

Yum es una herramienta sumamente útil para el manejo de paquetería RPM. Aprender a crear en el disco duro las bases de datos para los depósitos yum resulta práctico puesto que no hay que no habrá necesidad de recurrir hacia los depósitos localizados en servidores en Internet y consumir innecesariamente ancho de banda en el proceso.

Procedimientos

Primero se deben generar los directorios que alojarán los depósitos. Uno para la paquetería incluida en los discos de instalación y otro para las actualizaciones:

mkdir -p /var/ftp/pub/os
mkdir -p /var/ftp/pub/updates

Tome todos los discos de instalación y copie íntegramente su contenido hacia el interior del directorio localizado en la ruta /var/ftp/pub/os/ con el siguiente procedimiento:

mount /media/cdrom
cp -Rf /media/cdrom/* /var/ftp/pub/os/
eject

Del mismo modo, si dispone del disco compacto correspondiente, copie (o bien descargue) todas las actualizaciones dentro del directorio localizado en la ruta /var/ftp/pub/updates/ con el siguiente procedimiento:

mount /media/cdrom
cp -Rf /media/cdrom/* /var/ftp/pub/updates/
eject

Una vez copiado todo al disco duro, hay que instalar el paquete createrepo, incluido en los discos de instalación de CentOS y White Box Enterprise Linux.

yum -y install createrepo

Una vez instalado, solo se necesita ejecutar createrepo sobre cada directorio a fin de generar los depósitos yum:

createrepo /var/ftp/pub/os/
createrepo /var/ftp/pub/updates/

Los depósitos generados se pueden acceder localmente utilizando las siguientes líneas como contenido del fichero *.repo localizado dentro de /etc/yum.repos.d/ en lugar de las que apuntan hacia servidores en Internet:

[base]
name=Enterprise Linux $releasever - $basearch - base
baseurl=file:///var/ftp/pub/os/
gpgcheck=1

[updates-released]
name=Enterprise Linux $releasever - $basearch - Updates Released
baseurl=file:///var/ftp/pub/updates/
gpgcheck=1

Si se van a acceder estos mismo depósitos utilizando el servicio FTP, y suponiendo que el servidor va a utilizar 192.168.1.1 como dirección IP, las máquinas cliente deben utilizar lo siguiente:

[base]
name=Enterprise Linux $releasever - $basearch - base
baseurl=ftp://192.168.1.1/pub/os/
gpgcheck=1

[updates-released]
name=Enterprise Linux $releasever - $basearch - Updates Released
baseurl=ftp://192.168.1.1/pub/updates/
gpgcheck=1

Si utiliza la opción gpgcheck=1, antes deberá importar las llaves públicas GPG que están en el disco 1 de instalación del sistema.

mount /media/cdrom
rpm --import /media/cdrom/*KEY*

Si creo un depósito con el disco de extras de curso, la llave pública de Alcance Libre está en el directorio raíz del CD.

Si utiliza Red Hat Enterprise Linux 3.0, CentOS 3.0 o White Box Enterprise Linux 3.0, se utiliza yum-arch en lugar de createrepo y /mnt/cdrom en lugar de /media/cdrom.

White Box Enterprise Linux 4.0 no incluye yum por defecto, por lo que hay que instalarlo manualmente desde los discos de instalación.

Con los paquetes «yum-updatesd» o «yum-updateonboot» se puede hacer una actualización de software automática

Fuentes:

http://www.alcancelibre.org/staticpages/index.php/como-yum-createrepo

http://es.wikipedia.org/wiki/Yellow_dog_Updater,_Modified

Scripts

Para cambiar de mayúscula a minúscula:

#!/bin/bash
for f in *; do
mv $f `echo $f | tr '[a-z]' '[A-B]'`
done

Crear 10 archivos vacíos de forma consecutivas:
#!/bin/bash
CONT=0
for I in $(seq 1 10)
do
touch archivo-$CONT-$(date +%d-%m-%Y).txt
echo "Estamos en el bucle numero $CONT"
let CONT++
done

Bucles For, Until y While:
For:
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
For tipo C
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done
While:
#!/bin/bash
CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo El contador es $CONTADOR
let CONTADOR=CONTADOR+1
done

Until:
#!/bin/bash
CONTADOR=20
until [ $CONTADOR -lt 10 ]; do
echo CONTADOR $CONTADOR
let CONTADOR-=1
done

Select para menús sencillos:
#!/bin/bash
OPCIONES="Hola Salir"
select opt in $OPCIONES; do
if [ "$opt" = "Salir" ]; then
echo done
exit
elif [ "$opt" = "Hola" ]; then
echo Hola Mundo
else
clear
echo opción errónea
fi


done

Operadores relacionales aritméticos

-lt (<)

-gt (>)

-le (<=)

-ge (>=)

-eq (==)

-ne (!=)

Eliminar espacios en blanco de un archivo:

for i in *; do mv "$i" "`echo $i | tr ' ' '_'`"; done

O también así:
for i in *; do
nuevo=`echo $i | sed -s 's/\ //g'`;
mv "${i}" ${nuevo};
done

Renombrar archivos mp3:

Vamos a cambiar de nombre a muchos
archivos, son archivos mp3 y la estructura es la siguiente:
Grupo - cancion - num - Disco.mp3 (el grupo tiene espacios en blanco) y quiero que termine en num-cancion.mp3. for i in *.mp3 do titulo=`id3 -lR $i | grep -e "^Title" | cut -f2- -d ' '` artista=`id3 -lR | grep -e "^Artist" | cut -f2- -d ' '` album=`id3 -lR | grep -e "^Album" | cut -f2- -d ' '` num=`id3 -lR | grep -e "^Track" | cut -f2- -d' '`

mv «$i» «$artista-$titulo-$num-$album.mp3»
done

Lees directamente de cada fichero mp3 la información que tiene para renombrar el archivo con su contenido.


Fuente:
http://pacodebian.iespana.es/bash.html
http://sed.sourceforge.net/grabbag/tutorials/
http://groups.google.com.mx/group/es.comp.os.linux.programacion/
http://www.unix.com/es/shell-programming-scripting/98826-remove-blank-spaces-text-file.html


Backup y Restauración de base datos PostgreSQL

Preparamos la configuración de PostgreSQL:

Por razones de seguridad estableceremos la nueva contraseña al usuario del sistema creado por PostgreSQL:

$ sudo passwd postgres

Cambiar los privilegios de acceso al shell del usuario postgres con el siguiente comando:

$ sudo vipw

Y cambiamos el shell del usuario postgres de «/bin/false» a «/bin/bash». Luego salimos grabando con escape «:wq». Para verificar si la instalación fue satisfactoria accedemos a la shell del servidor de bases de datos:

$ sudo su postgres -c «psql template1»

Si el acceso ha sido satisfactorio cambiamos la contraseña al usuario predeterminado del servidor de bases de datos:

template1=# ALTER USER postgres WITH PASSWORD ‘nueva_contraseña’;

Te saldrá el siguiente mensaje confirmando la operación:

ALTER ROLE

Sal de la shell del servidor de bases de datos con el comando \q :

template1=# \q

[editar]
Configuración
[editar]
Permitir conexiones remotas

Por motivos de seguridad, la configuración por defecto no admite conexiones externas. Para habilitarlas tenemos que editar el fichero /etc/postgresql/8.2/main/postgresql.conf. ( En otras distribuciones de Linux, estos archivos de configuración se encuentran en otros directorios, si no se encuentran el /etc, hacer una busqueda con «find / -name postgresql.conf»).

$ sudo gedit /etc/postgresql/8.2/main/postgresql.conf

Ahora buscamos las siguientes líneas que se encuentran comentadas:

#listen_addresses = ‘localhost’

Y la substituimos por la siguiente línea:

listen_addresses = ‘*’

Posteriormente buscamos la siguiente línea y le quitamos la marca de comentario:

#password_encryption = on

Y nos debe quedar lo siguiente:

password_encryption = on

Guardamos los cambios y reiniciamos el demonio para que los cambios surjan efecto:

$ sudo /etc/init.d/postgresql-8.2 restart

[editar]
Configurar la lista de acceso

La configuración de la lista de acceso permite decirle a PostgreSQL qué método de autentificación usar y establecer relaciones de confianza para ciertas máquinas y redes. Hay que editar el fichero /etc/postgresql/8.2/main/pg_hba.conf:

$ sudo vi /etc/postgresql/8.2/main/pg_hba.conf

Al final del archivo se encuentra una lista de acceso predeterminada, ahora, dependiendo de su necesidad puedes hacer lo siguiente:

* Si necesita que cualquier usuario se conecte por medio de una dirección IP en especifico, agregue al final la siguiente línea:

host all all 192.168.1.4 255.255.255.0 md5

Imagen:Nota clasica.png La dirección IP y la SubMascara de Red son ejemplos, cámbielas por datos del usuario que requiera realizar la conexión.

* Si necesita que cualquier usuario se conecte por medio de una IP determinada sin importar el password (confiamos en dicha IP), la línea es:

host all all 192.168.1.4 255.255.255.255 trust

* Si necesita que cualquier usuario (usuario de base de datos autentificándose, claro) se conecte por medio de cualquier dirección IP, agregue al final la siguiente línea:

host all all 0.0.0.0 0.0.0.0 md5

* Si necesita que un usuario determinado se conecte a una base de datos determinada por medio de una dirección IP en especifico, agregue al final la siguiente línea:

host MyDataBase MyUser 192.168.1.4 255.255.255.0 md5

* Guarda los cambios realizados en el archivo y reinicia el demonio para que los cambios surjan efecto:

$ sudo /etc/init.d/postgresql-8.2 restart

Imagen:Nota clasica.png Para mayor información de la configuración de la lista de acceso, viste la pagina Web del proyecto de traducción del libro PostgreSQL Práctico, y consulta el capitulo Estructura del Archivo pg_hba.conf.

[editar]
Gestión de usuarios

Los usuarios de PostgreSQL tienen un par de capacidades que definimos en su creación. Me explico: un usuario puede o no crear más usuarios y un usuario puede o no crear bases de datos. En el ejemplo que puedes ver a continuación creamos un usuario que no puede crear más usuarios (no es un administrador) pero puede crear más bases de datos. El modificador -P hace que nos pregunte por el password que le asignaremos al usuario. De otra manera el usuario se creará sin password.

$ createuser -A -d -P -h host -U usuario nuevo_usuario
Enter password for user «nuevo_usuario»:
Enter it again:

Como acabo de comentar, existen usuario administradores (pueden crear otros usuarios). Como es lógico este comando debe ser ejecutado por un usuario con esa característica.

Análogamente podemos eliminar un usuario de esta forma:

$ dropuser -h host -U usuario usuario_borrar

[editar]
Copia de seguridad

Para hacer una copia de seguridad de una base de datos tiene el siguiente comando:

$ pg_dump -h host -U usuario nombre_bd > nombre_bd.sql

Para hacer una copia de seguridad de todas las bases de datos PostgreSQL de un servidor, usa este escript:

#!/bin/bash

#-------------------------------

# script para realizar backup

# de todas las bases de datos

#-------------------------------

HOST=localhost

PGPASSWORD="postgres"

LOCAL_DIR=`pwd`

BACKUP_DIR=$LOCAL_DIR/backup

DATE_BACKUP=$(date '+%Y%m%d')

echo $DATE_BACKUP

## -- END CONFIG --##

if [ ! -d $BACKUP_DIR ]; then

        mkdir -p $BACKUP_DIR

fi

# Selecciona todas las BD

POSTGRE_DBS=$(psql -h $HOST -U postgres -l password=postgres | awk '(NR > 2) && (/[a-zA-Z0-9]+[ ]+[|]/) && ( $0 !~ /template[0-9]/) { print $1 }');

for DB in $POSTGRE_DBS ; do

      echo"sBackuping PostgreSQL data from $DB@$HOST"

       PGPASSWORD="postgres" pg_dump -h $HOST -U postgres $DB > $BACKUP_DIR/$DB-$DATE_BACKUP.sql

done

Para restaurar una copia de seguridad, los archivos .sql y .dump:

psql -U postgres -d dbtaller12 -h localhost -f  backup_basedatos.sql

psql -d nombre_base_datos -f archivo.pgdump

Archivos .backup
pg_restore -i -h localhost -p 5432 -U postgres -v «respaldo-basedatos.backup»

Fuente:
http://www.guia-ubuntu.org/index.php?title=PostgreSQL#Permitir_conexiones_remotas

Permitir conexiones remotas a MySql Server

# Permitir las conexiones desde un host remoto:
Editamos el archivo de Configuración
vi /etc/mysql/my.cnf (y modificamos la línea)
bind-address = 127.0.0.1 (la cambiamos por)

bind-address = 0.0.0.0

# Acceso conexiones remotas usuario root en mysql (para usar alguien externo):
$ mysql -u root -p

> GRANT ALL ON *.* TO root@’%’ IDENTIFIED BY ‘password_user’;
> FLUSH PRIVILEGES;

y probamos la conexión remota:

Comando de Linux, con expresiones regulares

Comando grep

El comando grep nos permite buscar, dentro de los archivos, las líneas que concuerdan con un patrón. Bueno, si no especificamos ningún nombre de archivo, tomará la entrada estándar, con lo que podemos encadenarlo con otros filtros.

Por defecto, grep imprime las líneas encontradas en la salida estándar. Es decir, que podemos verlo directamente la pantalla, o redireccionar la salida estándar a un archivo.

Como tiene muchísimas opciones, vamos a ver tan sólo las más usadas:

-c En lugar de imprimir las líneas que coinciden, muestra el número de líneas que coinciden.

-e PATRON nos permite especificar varios patrones de búsqueda o proteger aquellos patrones de búsqueda que comienzan con el signo -.

-r busca recursivamente dentro de todos los subdirectorios del directorio actual.
-v nos muestra las líneas que no coinciden con el patrón buscado.
-i ignora la distinción entre mayúsculas y minúsculas.
-n Numera las líneas en la salida.
-E nos permite usar expresiones regulares. Equivalente a usar egrep.
-o le indica a grep que nos muestre sólo la parte de la línea que coincide con el patrón.
-f ARCHIVO extrae los patrones del archivo que especifiquemos. Los patrones del archivo deben ir uno por línea.
-H nos imprime el nombre del archivo con cada coincidencia.

Algunos ejemplos:
– Buscar todas las palabras que comiencen por a en un archivo:
$ grep «a*» archivo

Otra forma de buscar, sería:
$ cat archivo | grep «a*»

– Mostrar por pantalla, las líneas que contienen comentarios en el archivo /boot/grub/menu.lst:
$ grep «#» /boot/grub/menu.lst

– Enviar a un fichero las líneas del archivo /boot/grub/menu.lst que no son comentarios:
$ grep -v «#» /boot/grub/menu.lst

– Contar el número de interfaces de red que tenemos definidos en el fichero /etc/network/interfaces:
$ grep -c «iface» /etc/network/interfaces

– Mostrar las líneas de un fichero que contienen la palabra BADAJOZ o HUELVA:
$ grep -e «BADAJOZ» -e «HUELVA» archivo

– Mostrar las líneas de un fichero que contienen la palabra BADAJOZ o HUELVA, numerando las líneas de salida:
$ grep -n -e «BADAJOZ» -e «HUELVA» archivo

– Mostrar los ficheros que contienen la palabra TOLEDO en el directorio actual y todos sus subdirectorios:
$ grep -r «TOLEDO» *

Veamos algunos ejemplos con expresiones regulares:

– Obtener la dirección MAC de la interfaz de red eth0 de nuestra máquina:
$ ifconfig eth0 | grep -oiE ‘([0-9A-F]{2}:){5}[0-9A-F]{2}’

Sacamos la dirección MAC de la interfaz eth0 de nuestra máquina haciendo un:
ifconfig eth0

Y aplicando el filtro grep:
grep -oiE ‘([0-9A-F]{2}:){5}[0-9A-F]{2}’

Las opciones que he usado en grep son:

-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
-E Indica que vamos a usar una expresión regular extendida.

En cuanto a la expresión regular, podemos dividirla en dos partes:
([0-9A-F]{2}:){5} Buscamos 5 conjuntos de 2 carateres seguidos de dos puntos
[0-9A-F]{2} seguido por un conjunto de dos caracteres.

Como las direcciones MAC se representan en hexadecimal, los caracteres que buscamos son los números del 0 al 9 y las letras desde la A a la F.

– Extraer la lista de direcciones de correo electrónico de un archivo:
grep -Eio ‘[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}’ fichero.txt

Utilizo las mismas opciones que en el caso anterior:

-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
-E Indica que vamos a usar una expresión regular extendida.

Analicemos ahora la expresión regular:
[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}

Al igual que antes, la vamos dividiendo en partes:

[a-z0-9._-]+ Una combinación de letras, números, y/o los símbolos . _ y – de uno o más caracteres

@ seguido de una arroba

[a-z0-9.-]+ seguido de una cadena de letras, números y/o los símbolos . y –

[a-z]{2,4} seguido de una cadena de entre dos y cuatro caracteres.

– Obtener la dirección IP de la interfaz de red eth1 de nuestra máquina:

$ ifconfig eth1 | grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’ | grep -v 255

En el ejemplo anterior, hemos tomado la información que nos ofrece ifconfig:
ifconfig eth1

Hemos filtrado dicha información con el comando grep, obteniendo todas las direcciones IP que aparecen:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’

Por último, hemos filtrado la salida del comando anterior, para eliminar la dirección de broadcast junto con la máscara de red para quedarnos sólo con la dirección IP de la máquina:
grep -v 255

La línea anterior no mostraría las líneas que no contengan el valor 255, es decir, las direcciones de broadcast y máscara de red.

Analicemos ahora el comando grep:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’

Al igual que en los otros dos ejemplos de expresiones regulares uso las opciones -oiE en el comando grep:

-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
-E Indica que vamos a usar una expresión regular extendida.

En cuanto a la expresión regular:
‘([0-9]{1,3}\.){3}[0-9]{1,3}’

([0-9]{1,3}\.){3}: Representa 3 bloques de entre uno y tres dígitos separados por puntos. Observemos que como el punto es un metacaracter, tengo que usar el caracter de escape \ para que no sea interpretado como un metacaracter, sino como un carácter normal.
[0-9]{1,3}: Representa el último bloque de la dirección IP, que está formado por un número de entre 1 y 3 dígitos.

El shell de linux: Manipulación de cadenas
En bash podemos realizar operaciones de manipulación de cadenas, como por ejemplo:

* Obtener la longitud de una cadena.
* Buscar caracteres dentro de una cadena.
* Extraer una subcadena de una cadena.

Obtener la longitud de una cadena de caracteres.-
Podemos obtener la longitud de una cadena de tres formas:

* ${#cadena}

* expr length $cadena

* expr «$cadena» : ‘.*’

Ejemplos:

$ micadena=»Bienvenido al mundo de Linux»

$ echo «La longitud de la cadena es: `expr length $micadena`»
$ echo «La longitud de la cadena obtenida de otro modo: `${#micadena}`»

Buscar una cadena dentro de otra cadena de caracteres.-

Podemos averiguar cual es la posición de una cadena dentro de otra, utilizando las siguiente expresión:

expr index cadena_donde_buscar cadena_a_buscar

Devuelve la posición donde encuentra los caracteres a buscar dentro de la cadena, si no, devuelve un 0.

Ejemplo:

micadena=»Bienvenido al mundo de Linux»
cadenaabuscar=»Linux»
echo “La cadena $buscar se encuentra en la pos `expr index $micadena $cadenaabuscar`”

Como podemos ver, index busca una cadena, pero si lo que queremos utilizar como patrón de búsqueda es una expresión regular, usaremos:

expr match cadena_donde_buscar patrón_caracteres_buscar

Ejemplo:

cadena=»342 ovejas en el redil»
numero=`expr match $cadena [0-9]*`
echo «El número de dígitos al comienzo de la cadena $cadena es: $numero»

Extraer una subcadena de una cadena de caracteres.-

Si queremos extraer una subcadena de una cadena de caracteres, utilizamos la siguiente expresión:

expr substr cadena posición n_caracteres

Para extraer una subcadena de una cadena indicamos la cadena, la posición y longitud a extraer.

Ejemplo:

$nif=»70245678D»
echo “El DNI de $nif es `expr substr $nif 1 8`”
echo «La letra del $nif es `expr substr $nif 9 1`»

Comando let

El comando let nos permite trabajar fácilmente con variables numéricas en scripts.
Por ejemplo: Supongamos que queremos multiplicar por 2 el valor de una variable y almacenar el resultado en otra:

$ simple=4
$ let doble=simple*2

Si después de ejecutar estas dos instrucciones en un terminal, hacemos un:

$ echo $doble

Veremos que la variable doble vale 8.

Un ejemplo completo: Hacer un bucle while que incremente el valor de una variable CONTADOR y vaya mostrando los valores que toma dicha variable:

#!/bin/bash

CONTADOR=0
MAX=20

while [ $CONTADOR -lt $MAX ]; do
let CONTADOR=CONTADOR+1
echo El contador es $CONTADOR

done

Comando find

Utilizamos este comando para buscar archivos dentro de una jerarquía de directorios. Pero, lo mejor de todo es que no sólo podemos buscar, sino que, además, podemos ejecutar acciones sobre los elementos localizados por el comando find.

Por otro lado, podemos realizar la búsqueda mediante varios criterios.

La sintaxis de este comando es:

find [ruta…] [expresión]

Veamos un ejemplo sencillo: Queremos buscar los archivos de imágenes con extensión .jpg en el directorio del usuario ambrosio:

$ find /home/ambrosio -name «*.jpg»

Otro ejemplo: Imaginemos que quiero listar los directorios que hay en el directorio actual:
$ find ./ -maxdepth 1 -type d

Ahora imaginemos que quiero listar los ficheros que se han modificado hoy en el directorio actual:

$ find ./ -mtime 0 -type f

Si quisieramos borrar todos los subdirectorios del directorio /var/backup que tengan una antigüedad mayor de 20 días:

$ find /var/backup -mtime +20 -type d -exec rm -f {} \;

Otro ejemplo: Queremos borrar todos los directorios del sistema que contengan la palabra sane:
# find / -name «*sane*» -type d -exec rm -fr {} \; 2>/dev/null

Si lo que queremos es borrar todos los ficheros del sistema que contengan la palabra sane, no tenemos más que cambiar el tipo en el comando anterior:

# find / -name «*sane*» -type d -exec rm -fr {} \; 2>/dev/null

Otro ejemplo: Imaginemos que queremos recopilar todos los ficheros mp3 que tenemos repartidos en diferentes directorios y moverlos a un único directorio:

# find / -name «*.mp3» -exec mv {} /compartido/musica/ \;

Expresiones regulares

Una expresión regular es un patrón que nos permite buscar un texto formado por metacaracteres y caracteres ordinarios.

Los metacaracteres son ciertos caracteres con un significado específico dentro de una expresión regular. Estos caracteres tienen un significado que va más allá del símbolo que representan y tienen un comportamiento especial en una expresión regular.

Aquí tenéis una lista de metacaracteres que usamos en expresiones regulares:

* . Significa cualquier caracter.
* ^Indica el principio de una línea.
* $ Indica el final de una línea.
* * Indica cero o más repeticiones del caracter anterior.
* + Indica una o más repeticiones del caracter anterior.
* \< Indica el comienzo de una palabra.
* \> Indica el final de una palabra.
* \ Caracter de escape. Da significado literal a un metacaracter.
* [ ] Uno cualquiera de los caracteres entre los corchetes. Ej: [A-Z] (desde A hasta Z).
* [^ ] Cualquier caracter distinto de los que figuran entre corchetes: Ej: [^A-Z].
* { } Nos permiten indicar el número de repeticiones del patrón anterior que deben darse.
* | Nos permite indicar caracteres alternativos: Ej: (^|[?&])
* ( ) Nos permiten agrupar patrones. Ej: ([0-9A-F]+:)+

Ojo. En las expresiones regulares se distingue entre mayúsculas y minúsculas.

Si queremos representar un caracter entre la a y la z, lo haremos de la siguiente manera: [a-z]

Dentro del conjunto, podemos especificar todos los caracteres que queramos. Por ejemplo: [a-zA-Z] representaría los caracteres alfabéticos en minúsculas y mayúsculas. Eso sí. El conjunto representa a un sólo caracter.

Si lo que queremos es representar identificar un número o una letra, podríamos hacerlo así:
[a-zA-Z0-9]

Los conjuntos pueden representarse, nombrando todos y cada uno de los elementos, o el intervalo. Ej: [0-9] representa lo mismo que [0123456789].

Si queremos representar un número que se compone de cero o más dígitos: [0-9]*

Y si queremos representar un número que se compone de uno o más dígitos: [0-9]+

Si ahora queremos representar cualquier caracter menos los dígitos: [^0-9]

Ahora, imaginemos que queremos representar un número de 5 dígitos: [0-9]{5}

Y si quisieramos representar una palabra que tiene entre dos y cuatro caracteres: [a-zA-Z]{2,4}

Dentro de los conjuntos de caracteres individuales, se reconocen las siguientes categorías:

[:alnum:] alfanuméricos
[:alpha:] alfabéticos
[:cntrl:] de control
[:digit:] dígitos
[:graph:] gráficos
[:lower:] minúsculas
[:print:] imprimibles
[:punct:] de puntuación
[:space:] espacios
[:upper:] mayúsculas
[:xdigit:] dígitos hexadecimales
Vamos a ver algunos ejemplos de expresiones regulares:

# grep ‘^La’ fichero
El comando anterior nos devuelve todas las líneas del fichero que comienzan por La.

# grep ‘^ *La’ fichero
El comando anterior nos devuelve todas las líneas del fichero que comienzan por cualquier número de espacios seguido de La.

# grep ‘^\..*’ fichero

El comando anterior nos devuelve todas las líneas del fichero que comienzan por punto y tienen cualquier número de caracteres.

# ls -la | grep ‘ \..*’

El comando anterior nos devuelve la lista de ficheros que comienzan por un espacio seguido de un punto y cualquier número de caracteres, es decir, la lista de ficheros ocultos.

# ls -l | grep ‘^d’
El comando anterior nos devuelve la lista de ficheros que comienzan por d, es decir, la lista de directorios.

Awk

Awk busca ciertos patrones en la entrada, y la procesa de la manera especificada. Awk tiene una gran funcionalidad, pero esta mayor funcionalidad tiene su coste reflejado en una mayor complejidad del lenguaje.

awk dispone de un lenguaje completo, sintácticamente similar a C que tiene una gran potencia a la hora de reconocer patrones en la entrada, ya que permite especificar combinaciones de expresiones regulares.

Además, no es necesario procesar la entrada línea a línea. Awk permite escoger el carácter que indica el fin de un registro y procesar la entrada de registro en registro (En el lenguaje awk, un ‘registro’ es el equivalente a una ‘línea’).

Awk separa automáticamente cada registro en campos que pueden utilizarse individualmente.

Por defecto, un registro es una línea del fichero, lo que significa que el separador de registros es ‘\n’.

Por defecto, un campo es todo aquello que esté separado por espacios en blanco, es decir, una palabra. El separador de campos por defecto es ‘[ \t]’ (espacio y tabulador).

Una posible sintaxis de awk sería:

awk [fichero_entrada]

Un programa de awk es una secuencia de sentencias patrón-acción, con un formato determinado, en el que las acciones se ejecutarán si en el registro actual se cumple el patrón.

El formato es el siguiente:

patrón {accion}

Suele ser necesario encerrar los programas de awk entre comillas, para evitar que el shell las interprete como caracteres especiales.

Hay que tener en cuenta dos cosas:

* Si no hay patrón, las acciones se ejecutan en todos los registros.

* Si no hay acciones, lo que se hace es ejecutar la acción por defecto, que es copiar el registro en la salida estándar.

Veamos un par de ejemplos o tres de uso de awk:

* Mostramos el nombre de usuario de todos los usuarios logueados en la máquina:

who|awk ‘{print $1}’

* Borramos todas las líneas vacías de un fichero:

awk ‘!/^$/ {}’ fichero

* Mostramos el nombre de usuario y el intérprete que usa:

awk ‘BEGIN {FS=»:»}; {print $1,$NF | «sort»}’ /etc/passwd

* Mostramos el nombre completo del usuario y su login:

awk ‘BEGIN {FS=»:»}; {print $1,$5 | «sort»}’ /etc/passwd

Variables

Como ya hemos dicho, awk dispone de un lenguaje completo, y, como cualquier otro lenguaje, dispone de variables. Las variables pueden ser de dos tipos:

* Variables predefinidas.
* Variables definidas por el usuario.

Veamos cuales son las variables predefinidas:

* FS (Field separator): Permite indicar a awk cuál es el caracter que separa los campos. Por defecto es el espacio. La forma de indicar a awk el caracter de separación de campos es la siguiente: FS = “caracter”. Por ejemplo: FS = «,». Si hacemos FS = «», estamos indicando a awk que cada carácter es un campo.
* NF (Number of fields): Contiene el número total de campos que contiene el registro que se está leyendo en cada momento.
* RS (Record separator): Contiene el carácter que indica a awk en qué punto del archivo acaba un registro y empieza el siguiente. Por defecto es el caracter “\n”.

* NR (Number of record): Contiene el número de orden del registro que se está procesando en cada momento.

* OFS (Output FS): La instrucción print inserta en la salida un carácter de separación cada vez que aparece una coma en el código. Mediante OFS, podemos indicar a awk que separe los campos mediante el separador que le indiquemos. Por ejemplo: OFS = «;»

En cuanto a las variables definidas por el usuario, se crean directamente al hacer referencia a ellas en expresiones.

Las variables pueden ser:

* Escalares: Almacenan un solo valor.

* Vectoriales: Como vectores o arrays. En awk, se pueden crear arrays asociativos, dado que el lenguaje nos permite usar una cadena como índice del array. Para referirnos a un elemento dentro de un array, lo haremos: nombre[ subíndice ].

Campos de entrada

En Awk se considera cada registro del archivo de entrada como una sucesión de campos delimitados por un carácter dado. Este carácter es, por defecto, el espacio.
En cualquier caso, podemos indicar a awk que considere otro carácter como separador de campos mediante la opción FS, tal y como podemos ver en ejemplos anteriores.

Cada uno de estos campos se numera de forma correlativa, según su posición en la línea (o registro), de la siguiente manera: $1, $2, $3, … Además, también podemos referirnos a la línea entera con $0.

Por otra parte, se puede forzar a procesar una línea carácter a carácter, dejando la variable “separador de campos” FS sin contenido. Si hacemos ésto, en $1 se tendrá el primer carácter de la línea, en $2 el segundo, etc.

El otro día me encontré con el siguiente ejercicio:

Hacer un script que visualice la lista de usuarios que se encuentran conectados en el sistema, mediante el siguiente formato: nº orden — nombre usuario, totalizando el nº de usuarios. Ejemplo:

1 — root
2 — df01
3 — df02

Utilizando awk, la solución es tan sencilla como la siguiente:
#/bin/bash
who -u|awk ‘BEGIN { i=0 } { i+=1; print i,»-«,$1 } END { print «Total usuarios » i }’

Estructura básica de un programa con awk

Para entender fácilmente la estructura de un programa con awk, podemos fijarnos en el ejemplo anterior, en el que tenemos tres bloques:

* BEGIN { i=0 }
* { i+=1; print i,»-«,$1 }
* END { print «Total usuarios » i }

El primero, se ejecuta al inicio. En este caso, hemos utilizado el bloque BEGIN para inicializar la variable i con valor 0.
El segundo bloque se ejecuta para cada patrón (o registro, como queramos llamarlo). En este caso, incrementa el valor de i, y lo muestra por pantalla seguido de un guión y el campo nº 1 (que en este ejemplo es el login del usuario) Como no hemos indicado ningún separador de campo, se toma por defecto el espacio.

El tercer bloque se ejecuta al final. ¿Y qué hace el bloque en el ejemplo? Imprimir el número total de usuarios.

Awk puede servirnos muy bien para procesar ficheros de texto, extraídos de bases de datos, en los que tenemos registros con campos de datos.

Como ya hemos dicho, awk dispone de un lenguaje completo, con sentencias, condicionales, bucles, estructuras … Una sentencia que puede sernos de utilidad en el procesamiento de ficheros, es el if. Veamos un ejemplo usando esta sentencia:

awk ‘{ if (x % 2 == 0) print «x is even»; else print «x is odd» }’

Comando diff

El comando diff nos permite comparar dos ficheros linea a linea y nos informa de las diferencias entre ambos ficheros. Diff tiene muchas opciones. Las que más uso son -w, -q, -y.

La sintaxis del comando es la siguiente:

diff [opciones] [fichero1] [fichero2]

Si queremos comparar dos ficheros, ignorando los espacios en blanco, utilizaremos el parámetro -w:

diff -w fichero1 fichero2

Si lo que queremos es que no nos muestre las diferencias, sino que tan sólo nos informe de si son diferentes o no:

diff -q fichero1 fichero2

Si queremos que nos muestre la salida con las diferencias marcadas a dos columnas:

diff -y fichero1 fichero2

Como en muchos otros comandos, también podemos utilizar la opción -i, que ignora la diferencia entre mayúsculas y minúsculas.

Comando date

date es otro de los comandos que utilizamos en ocasiones en scripts, como por ejemplo, cuando creamos un script que debe hacer copia de seguridad diaria. El nombre de las carpetas donde se almacena la copia de cada día se crea usando el comando date.

date presenta la fecha y la hora del sistema, datos que sólo puede modicar el usuario root y tiene que seguir el siguiente formato: MM DD HH MM [AA][ss]

Si utilizamos el comando date a secas, se nos mostrará la fecha y hora de la siguiente manera: día de la semana, mes, día, hora, zona horaria, año. Por ejemplo:

lun mar 3 12:51:22 CET 2008

Pero, normalmente en los scripts sólo utilizo el año, mes y día.

Para ver la fecha mediante otro formato, podemos hacerlo utilizando la siguiente sintaxis del comando:

date +formato

Opciones de formato de hora:

* H : presenta la hora en el formato de 00 a 23.
* k : presenta la hora de 0 a 23.
* M : presenta los minutos de 00 a 59.
* p : añadir AM o PM.
* l : presenta la hora de 1 a 12.
* r : presenta horas minutos segundos [A/P]o[A/M].
* T : presenta horas minutos segundos.
* a : presenta el día de la semana abreviado.
* A : presenta el día de la semana completo.
* b : presenta el mes abreviado.
* B : presenta el mes completo.

Opciones de formato de fecha:

* D : presenta meses días años.
* d : presenta día.
* m : presenta mes.
* y : presenta año con el formato 01.
* Y : presenta año con el formato 2001.
* j : nos presenta el número de día juliano.

Ejemplo práctico:

nombrefichero=`date +»backup%Y%m%d»`

De este modo, estoy creando un nombre de fichero que tendrá la siguiente forma, por ejemplo: backup20080303

Comando sed

Este comando también lo usamos mucho, porque nos permite, de una forma cómoda, borrar líneas, registros o sustituir cadenas de caracteres dentro de las líneas.

* Para borrar una línea hacemos lo siguiente:

sed ‘nº_de_línead’ fichero

* Podemos indicar un número de línea concreto. Por ejemplo:

sed ‘1d’ fichero

* Podemos indicar un intervalo de líneas a borrar. Por ejemplo:

sed ‘3,5d’ fichero

* También podemos indicar que queremos borrar desde una determinada línea en adelante:

sed ‘3,$d’ fichero

* Otro ejemplo útil es borrar las líneas en blanco de un fichero:

sed ‘/^$/d’ fichero

A la hora de borrar, también podemos especificar una cadena, de tal forma que el comando borrará todas las líneas que contengan esa cadena. Ejemplo:

cat fichero | sed ‘/^[ ]*$/d’ > ficherodestino

Lo anterior borrará todas las líneas en blanco de fichero.

Otro de los usos más interesantes de sed es sustituir cadenas. Podemos sustituir una cadena por otra de la siguiente manera:

sed ‘s/cadena1/cadena2/’ fichero

Al ejecutar el comando anterior, se sustituye la primera cadena que encuentra por la segunda. Pero, si lo que queremos es sustituir todas las cadenas que encuentre, en cada una de las líneas, añadimos el parámetro g :

sed ‘s/cadena1/cadena2/g’ fichero

Por otra parte, también podemos hacer que sustituya la cadena1 por la cadena2 en un número de línea concreto:

sed ‘5 s/USUARIO/usuario/g’ fichero

Con cadenas de texto normales la cosa es sencilla, pero al que más y al que menos le resulta complicado cuando lo que hay que sustituir son caracteres especiales como el tabulador: \t o el caracter de nueva línea: \n. Pero veamos como tampoco es complicado: Imaginemos que tenemos un fichero con campos en los que el separador es el tabulador y queremos sustuir este caracter separador por otro caracter separador, como por ejemplo el punto y coma (;). Lo haremos de la siguiente manera:

sed ‘s/\t/;/g’ fichero

Publicado por Esteban M. Navas Martín en 11:23 3 comentarios Enlaces a esta entrada
Etiquetas: comandos, linux, scripts
El shell de linux: Comando tr
tr es un filtro que nos permite cambiar una determinada información de un archivo por otra.
Cambia cada uno de los caracteres especificados en el conjunto inicial por los caracteres especificados en el conjunto final.
El fichero de origen o fichero destino lo especificamos con los caracteres de redirección: .

Veamos un par de ejemplos o tres:

tr ‘:’ ‘ ‘ ficheropasswd
tr ‘[a-z]’ ‘[A-Z]’ listaalumnosmayusculas
tr ‘ ‘ ‘\n’ lineasusuarios
tr -s » » prueba2

Parámetros útiles:

* -s : Sustituye un conjunto de caracteres repetidos por uno sólo. Es muy útil cuando hay secuencias de caracteres que queremos borrar:

tr -s » » ficherodestino

* -c : Hace que se traduzcan todos los caracteres que no se encuentren especificados en el primer parámetro. En el siguiente ejemplo se traduce por una ? todo lo que no sean letras o números.

tr -c ‘[a-z][A-Z][0-9]’ ? ficherodestino

* -d : Borra los caracteres que especifiquemos.

tr -d ‘[a-z][0-9]’ ? ficherodestino

Comando uniq
uniq es uno de los filtros que nos sirve para filtrar o eliminar las líneas repetidas con los que trabajamos bastante.

Podemos darle varios usos. El principal es eliminar lineas repetidas, tal y como hace el parámero -u del comando sort.

* Para visualizar líneas no repetidas no tenemos que indicar ningún parámetro, aunque podemos pasarle el parámetro -u.

* También podemos usar el parámetro -d para visualizar las líneas repetidas.

* También podemos utilizarlo para contar líneas repetidas, pasándole el parámetro -c.

Comando sort

sort es uno de los comandos que utilizamos mucho a la hora de realizar scripts.

Nos permite ordenar los registros o líneas de uno o más archivos.

La ordenación se puede hacer por el primer carácter, por el primer campo de la línea o por un campo distinto al primero en el caso de ficheros estructurados.

Podemos ordenar el contenido de un fichero de la siguiente manera:

sort fichero

Se realizaría la ordenación y el resultado se mostraría por pantalla. Así que, si lo que queremos es obtener el resultado de la ordenación en un fichero, haríamos:

sort fichero > ficheroordenado

Si lo que queremos es ordenar varios ficheros y añadir el resultado a otro, podemos indicar varios ficheros en la línea de entrada:

sort fichero1 fichero2 > fichero3

Y si lo que queremos es ordenar un fichero y dejar el resultado de la ordenación en el mismo fichero, podemos hacerlo con el parámetro -o (output):

sort -o f1 f1

Veamos una lista de los parámetros que pueden resultarnos más útiles a la hora de usar este comando:

* -f : Este parámetro nos sirve para indicar que las mayúsculas y las minúsculas se van a tratar de forma diferente y que por tanto se va a seguir un ordenamiento alfabético.
* -n : Este parámetro nos sirve para ordenar los campos numéricos por su valor numérico.
* -r : Nos permite realizar una ordenación inversa, es decir, de mayor a menor.
* +número : Este parámetro nos sirve para indicar la columna o campo por el que vamos hacer la ordenación.
* –field-separator= separador. Normalmente, se usa como delimitador de campos el espacio en blanco. Podemos utilizar el parámetro –field-separator para indicar que vamos a usar otro delimitador de campo cualquiera. Ej: –field-separator=, La opción abreviada de –field-separator es -t.
* -u : Nos permite suprimir todas las líneas repetidas después de realizar la ordenación.

Y algunos ejemplos con dichos parámetros:

Obtener un listado de los ficheros del directorio actual, ordenado por tamaño de archivo:
$ ls -l | sort +4n

Obtener un listado de los ficheros del directorio actual, ordenado de mayor a menor por tamaño de archivo:
$ ls -l | sort -r +4n

Obtener un listado de los ficheros del directorio actual, ordenado por nombre del archivo:
$ ls -l | sort +7

Ordenar un fichero eliminando las líneas repetidas:
$ sort -u fichero

Ordenar un fichero pen el que los campos están separados por comas, por el campo número 3:
$ sort -t, +3

Comando join

Un comando que nos puede resultar bastante util para mezclar información obtenida de dos ficheros relacionados es el comando join.

join se utiliza para crear un archivo mezclando otros dos que tienen un campo clave con información común. Por defecto, no tenemos que indicar ese primer campo común, pero podemos indicar otro campo distinto.
Para poder mezclar la información de ambos ficheros, los campos deben estar separados por un caracter, que por defecto es el espacio o tabulador.

Ejemplo:

join fichero1 fichero2

Los espacios iniciales se ignoran.

Si deseamos especificar un separador de campo específico, lo hacemos con el parámetro -t. Veamos un ejemplo en el que utilizamos como separador de campos los dos puntos:

join -t»:» profesores.txt grupos.txt

Pero imaginemos que el campo por el que queremos mezclar los ficheros no es el primero en ambos archivos. Pues bien, podemos indicar el número de campo por el que queremos hacer la mezcla en cualquiera de los archivos:

join -t»:» -2 2 profesores.txt grupos.txt

En el ejemplo anterior estamos indicando que la mezcla se debe realizar tomando el primer campo del primer fichero con el segundo campo del segundo fichero.

También podríamos indicar los campos de cada fichero por los que se debe mezclar:

join -t»:» -1 2 -2 2 profesores.txt grupos.txt

En este caso, mezclamos tomando como referencia el segundo campo del primer fichero con el segundo campo del segundo fichero.

Un detalle importante a destacar: Los ficheros deben estar ordenados por el campo que se van a mezclar.

Comando cut
El comando cut nos permite buscar y/o seleccionar columnas o campos dentro de un archivo estructurado.

En el caso de los campos, los archivos deben estar estructurados y entre campo y campo debe existir obligatoriamente un delimitador. Este delimitador puede ser: los dos puntos ( : ), el tabulador, espacio en blanco, u otro carácter.

Para seleccionar un campo dentro de un fichero debemos especificar el número de campo después del parámetro:

cut -f numerodecampo fichero

Por defecto, el delimitador es el tabulador. Si utilizamos otro delimitador, lo indicaremos mediante el parámetro -d . Por ejemplo:

cut -f numerodecampo -d»delimitador» fichero

Si trabajamos con columnas nos encontramos como primera referencia que tenemos campos de longitud fija, mientras que con los campos estos pueden ser de longitud variable.

El número de cada columna hace referencia a su posición dentro de la línea. Indicamos las columnas con el parámetro -c número de columna y fichero. Por ejemplo:

cut -c22-34 fichero

Autor: Esteban M. Navas Martín

Conectarse SSH con llaves (SSH Keys)

Los pasos serían:

-Ejecutar ssh-keygen en la máquina desde donde te vas a loguear:
 ssh-keygen -t rsa
en passphrase, pones cadena vacía (enter, enter)

Esto te genera 2 archivos (claves privada y pública):

  1. id_rsa
  2. id_rsa.pub

en la máquina destino fijate si tenes en tu home (el del usuario que se va a loguear) el archivo .ssh/authorized_keys si no existe (supongo que no), copiás ahí el contenido de tu clave pública (desde máquina origen) scp .ssh/id_rsa.pub:.ssh/authorized_keys

si ya existe el archivo lo que vas a tener que hacer es adosar el
contenido de tu clave pública al archivo de claves autorizadas de la
otra máquina.

algo asi:
– scp .ssh/id_rsa.pub :
– ssh
– cat id_rsa.pub >> .ssh/authorized_keys
– rm id_rsa.pub
– exit

Una vez hecho esto, cuando intentes loguearte por ssh, lo que harán las

máquinas será intercambiar claves públicas, y harán la autenticación sin
necesidad de pedirte password.