Algo de Linux: enero 2008

jueves, 31 de enero de 2008

Linux: Retener paquetes y restaurarlos

En muchas ocasiones nos interesa que el sistema no actualice determinados paquetes porque los que tenemos instalados son más actuales o los hemos compilado para unas necesidades especificas que no cubren los que hay en los repositorios.

Por ejemplo: La versión de ffmpeg que hay en los repositorios de ubuntu no tiene soporte para amr. Así que he cogido el código fuente y la he compilado para que lo tenga. Pero cuando actualizo la lista de paquetes, el sistema me informa de que hay una versión más reciente en los repositorios. Como sé que esta versión no tiene soporte para amr, retengo el paquete para que no se actualice:

# echo "ffmpeg hold" | dpkg --set-selections

Es importante saber que los paquetes retenidos para apt no están retenidos para aptitude, y viceversa, por lo que deberemos retenerlos para el sistema que nos interese.

Esto es importante, porque si hemos retenido un paquete para apt y hacemos un aptitude upgrade no respetará el paquete retenido.
Lo mismo ocurre si retenemos un paquete para aptitude: Si hacemos un apt-get upgrade tampoco lo respetará.

Naturalmente, si usamos apt-get o aptitude indistintamente, sería recomendable que cuando retengamos un paquete lo hagamos para apt y para aptitude.

Retener paquetes para aptitude.

Podemos retener paquetes para aptitude de dos formas:

  • Mediante consola:
$ sudo aptitude hold nombre_del paquete
  • Mediante el menú de aptitude:
- Primero hacemos aptitude update para ver qué paquetes son actualizables.
- Una vez hecho lo anterior, ejecutamos aptitude en una consola.
- Buscamos en paquetes actualizables. Nos colocamos sobre el que deseamos retener.
- Una vez sobre el fichero retenido, pulsamos la tecla "=" y ya está.
- Y finalmente pulsamos q para salir.

Podemos restaurar paquetes para permitir su actualización con aptitude:

  • Mediante consola:
$ sudo aptitude unhold nombre_del_paquete
  • Mediante el menú de aptitude.

- Primero hacemos aptitude update para ver qué paquetes son actualizables.
- Una vez hecho lo anterior, ejecutamos aptitude en una consola.
- Buscamos en paquetes actualizables. Nos colocamos sobre el que deseamos retener.
- Una vez sobre el fichero retenido, pulsamos la tecla "=" y ya está.
- Y finalmente pulsamos q para salir.

Retener paquetes para apt y dpkg.

Para retener un paquete:

echo “nombre_del_paquete hold” | sudo dpkg --set-selections

Para restaurar el paquete y permitir su actualización:

echo “nombre_del_paquete install” | sudo dpkg --set-selections


miércoles, 30 de enero de 2008

Convertir videos .flv a .3gp

Me habían pedido convertir unos videos de youtube a formato 3gp para poder reproducirlos en el móvil. Así que como eran muchos, me puse a buscar información sobre el tema.

Como ya lo tengo resuelto, lo pongo aquí por si a alguien le interesa usarlo.

Debemos tener en cuenta que ffmpeg no viene compilado para usar el codec de audio amr, así que si queréis convertir de flv a 3gp, podéis descargar el ffmpeg compilado con soporte para amr desde aquí:
ffmpeg_amr.deb

Para hacer la conversión y no tener que estar pensando qué parámetros tengo que poner, he hecho un script, al que le pasamos como parámetros la lista de ficheros a convertir y el sólo los convierte. Podéis pasar una lista de ficheros o * para indicar que convierta todos los ficheros del directorio.

flva3gp.sh

#!/bin/sh

if [ $# -eq 0 ]; then
echo "Uso: $0 [lista de ficheros flv]"
exit
fi

if [ $1 = * ]; then
lista=`ls`
else
lista=$*
fi

for fichero in $lista; do
echo "Procesando $fichero."
ficherosalida=`echo $fichero|cut -f1 -d"."`.3gp
ffmpeg -i $fichero -s qcif -vcodec h263 -r 25 -b 200 -ab 64 -acodec mp3 -ac 1 -ar 8000 $ficherosalida
done

echo "Proceso concluido."

Que lo disfrutéis.

martes, 29 de enero de 2008

Conexión automática a la red del trabajo o a la red de casa con linux

Habitualmente utilizo en portátil tanto en casa como en el trabajo, y una de las cosas que siempre me han resultado pesadas ha sido cambiar la configuración de la red cada vez que voy a usar el ordenador en casa y volverla a cambiar para usarlo en el trabajo.

Así que un día que estaba bastante harto de hacer cambios diarios, me puse a configurar el portátil para que se conectara automáticamente a la red de casa o a la del trabajo dependiendo de donde lo conectara.

En casa me conecto por wifi a la red que tiene seguridad wep y en el trabajo por ethernet, así que necesité instalar:
  • ifplugd : monitorea si se establece link en la capa física (por ejemplo si un cable de red es conectado o si existe una asociación wireless activa).
  • guessnet : nos da herramientas para detectar a qué red estamos conectados.

¿Cómo instalarlas? Nada más fácil:

aptitude install ifplugd guessnet

Si tenéis vuestro punto de acceso con seguridad wpa tendréis que instalar también wpagui, que maneja la asociación wireless con un punto de acceso.

Una vez instalados los paquetes, modificamos el fichero /etc/network/interfaces. El mío quedó de la siguiente manera:

# /etc/network/interfaces

auto lo

iface lo inet loopback
address 127.0.0.1
netmask 255.0.0.0

iface ppp0 inet ppp
provider ppp0

mapping eth?
script guessnet-ifupdown
#map default: trabajo
map timeout: 3
#map verbose: true

iface trabajo inet static
address 192.168.1.2
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1

iface casa inet dhcp
test wireless essid C54APRA

# Si ninguna es encontrada, prueba DHCP
iface none inet dhcp


Veamos paso a paso en fichero de configuración:

auto lo

iface lo inet loopback
address 127.0.0.1
netmask 255.0.0.0

Las lineas anteriores definen el localhost y lo levantan automáticamente en el inicio.

iface ppp0 inet ppp
provider ppp0

Las dos líneas anteriores definen el interfaz del modem, por si en algún momento decido usarlo.

mapping eth?
script guessnet-ifupdown
map timeout: 3

Las líneas anteriores definen que las interfaces eth? como por ejemplo eth0, eth1 ... van a ser manejadas automáticamente.

iface trabajo inet static
address 192.168.1.2
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1

test peer address 192.168.1.1 mac 02:E0:52:EB:B6:DF

Las líneas anteriores definen que la conexión al trabajo se hace con ip estática. Y que, por decirlo de alguna manera, para determinar que nos estamos conectando a la red del trabajo comprobamos que hay un host (por ejemplo el router) con una IP y una MAC concreta.

iface casa inet dhcp
test wireless essid MICASA

Las dos líneas anteriores determinan que la conexión a la red de casa se hace mediante dhcp y para comprobar que se debe conectar a la red de casa, testeamos que existe una red con wifi con el nombre MICASA.

# Si ninguna es encontrada, prueba DHCP
iface none inet dhcp

Y, por último, las dos líneas anteriores nos sirven para que, si no encontramos la red de casa, ni la del trabajo, se pruebe a conectar por dhcp.

lunes, 28 de enero de 2008

Introducción a la creación de shell scripts con bash

Una de las cosas con la que trabajamos mucho los administradores linux es la programación de shell scripts, dado que éstos nos dan la posibilidad de preparar tareas que simplifican nuestro trabajo diario.

Veamos a continuación un pequeño guión introductorio sobre programación de shell scripts.

Para escribir un shell script necesitamos un editor de texto plano, como por ejemplo: nano o gedit. En realidad nos vale cualquier editor de texto, siempre y cuando el archivo lo guardemos como text/plain.


3. Uso de parámetros en scripts

Podemos usar parámetros en nuestros scripts. Dichos parámetros nos permitirán pasar valores externos que utilizaremos dentro:


$0 contiene el nombre nombre de nuestro script

$# contiene el número de parámetros con los que se ha invocado al shell

$n contiene los parámetros, con n de 1 a 9 (a $#)

{$n} cuando n > 9, tenemos qu especificar los parámetros entre llaves

$$
contiene el PID de nuestro proceso

$* todos los parámetros menos $0


6. Operadores de comparación

Podemos hacer comprobaciones sobre ficheros utilizando el comando test.

El comando test evalúa una expresión y retorna un valor que será cero si la expresión es verdadera o distinto de cero si la expresión es falsa.

Este comando tiene la siguiente sintaxis:

test expresion
[ expresion ]

donde EXPRESION puede ser una evaluación: de cadenas de caracteres, números enteros, archivos (evaluamos permisos y existencia del archivo) u operadores lógicos que permiten realizar una combinación de varias evaluaciones.

- Utilización abreviada del comando test.

En vez de escribir test EXPRESION, podemos escribir la EXPRESION entre corchetes( [ ] ) y el resultado será exactamente el mismo.

Ejemplo:

$ str="abc"
$ [ "$str" = "abc" ]
$ echo $?

Habitualmente el comando test se utiliza en conjunto con la sentencia if para evaluar distintos tipos de expresiones que veremos a continuación.


6.1. Operadores sobre ficheros

-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


6.2. Operadores lógicos

! 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


6.3. Operadores de comparación de números enteros

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 enteros n1 es mayor que n2
n1 -ge n2 cierto si los enteros n1 y n2 son iguales o n1 es mayor que n2
n1 -lt n2 cierto si el enteros n1 es menor que n2
n1 -le n2 cierto si los enteros n1 y n2 son iguales o n1 es menor que n2


6.4. Operadores de comparación de cadenas

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
s1 <> s2 cierto si la cadena de texto s1 es mayor que s2
-n cadena cierto si la longitud de la cadena de texto es distinta de cero


6.5. Operadores lógicos && y ||

Además de los anteriores, existen los operadores lógicos && (AND, multiplicación lógica) y || (OR, suma lógica), que se puede aplicar al valor de salida de los programas:

$ true && true ; echo $?
$ true && false ; echo $?
$ false && true ; echo $?
$ false && false ; echo $?

$ true || true ; echo $?
$ true || false ; echo $?
$ false || true ; echo $?
$ false || false ; echo $?

7. Sentencias de comparación

7.1. Sentencia if

Esta sentencia nos permitirá ejecutar un bloque de código, o u otro, dependiendo de como se evalue una condición.

La forma más simple tiene la siguiente sintaxis:

if CONDICION; then
bloque de comandos
fi

En este primer caso el bloque de comandos se ejecutará solo si la condición es evaluada a cierto.

Una segunda posibilidad es utilizar else:

if CONDICION; then
bloque de comandos b1
else
bloque de comandos b2
fi

En este segundo caso el bloque de comandos b1 se ejecutará si la condición es cierta. Si la condición fuera falsa, se ejecutará el bloque de comandos b2.

La condición puede ser, por ejemplo, una llamada al comando test o una operación lógica entre los valores de salida de diferentes comandos.

Ejemplo:

read numero
# comparamos cadenas de texto, así que usamos comillas
if [ $numero -eq 5 ]; then
echo Acerté tu número. Es el 5.
fi

7.2. Sentencia case

Se utiliza cuando el valor de una variable ha de ser contrastado con varios valores. Su sintaxis es la siguiente:

case variable in
patron1) comando1
comando2;;
patron2) comando3
comando4;;
....
....
esac

Comprueba si variable coincide con algunos de los patrones (patron1, patron2,...) y ejecuta los comandos asociados con la primera coincidencia que tiene lugar.

Sólo se ejecuta un único grupo de comandos.

El ";;" es el delimitador de los comandos que se ejecutaran para un determinado patrón y "esac" es el fin de la sentencia case.

Un ejemplo clásico de uso de la sentencia case es la creación de un menú:

!/bin/bash
##############################
# Genera un menú de opciones #
##############################
echo "[1] Listar archivos"
echo "[2] Ver directorio de trabajo"
echo "[3] Crear directorio"
echo "[4] Crear usuario"
read -p "Ingrese una opción: " OPCION
case $OPCION in
1) ls;;
2) pwd;;
3) read -p "Ingrese nombre del directorio a crear: " DIRECTORIO
mkdir $DIRECTORIO;;
4) if id | grep uid=0
then
read -p "Ingrese el nombre del usuario a crear: " NOMBREUSUARIO
useradd $NOMBREUSUARIO
else
echo "Se necesitan permisos de root"
fi;;
*) echo "Opción ingresada no valida, intentelo de nuevo"
exit 1;;
esac

8. Bucles

El shell nos aporta mecanismos para realizar tareas repetitivas mediante el empleo de estructuras que permiten repetir un bloque de comandos.

8.2. El bucle while

Es otra estructura de bucle que permite ejecutar un bloque de comandos mientras se evalúe una condición a cierto:

while CONDICION; do
bloque de comandos
done

Cada iteración se evalua la condición y en el momento que no sea cierta, el bucle termina.

Ejemplos de bucles:

# equivalente a seq 1 5
i=1
while [ $i -le 10 ]; do
echo $i
i=$(($i+1))
done

# leemos de stdin hasta que se introduzca la palabra 'salir'
read linea

while [ $linea != "salir" ]; do
read linea
done

9. Funciones

Una función o subrutina es una agrupación de comandos bajo un mismo nombre. Lo que nos permitirá dividir el programa en bloques y programar cada bloque por separado, o agrupar una serie de comandos que se ejecutan a menudo bajo un mismo nombre.

Veamos cuál es la sintaxis de una función:
nombre_funcion()
{
comando1
comando2
...
...
}

Luego, para ejecutar la función debemos llamarla por su nombre, igual que un comando:

...
nombre_funcion
...

Eso sí, debemos tener en cuenta que es necesario definir cada función antes de utilizarla. Veamos un ejemplo:

mostrar_menu ()
{
echo -e "\n"
echo "[1] Crear usuario"
echo -e "[2] Salir\n"
read -p "Elija una opción: " OPCION
}

crear_usuario ()
{
if [ id | grep uid=0 ]; then
read -p "Nombre del usuario a crear: " NOMBREUSUARIO
useradd $NOMBREUSUARIO
else
echo '*****************************'
echo "Se necesitan permisos de root"
echo '*****************************'
fi
}
############# Programa principal #################
while true; do
mostrar_menu
case $OPCION in
1) crear_usuario ;;
2) echo "Abandonando el programa..."
break;;
*) echo '********************************************'
echo "Opción ingresada no valida, intente de nuevo"
echo '********************************************';;
esac
done

viernes, 25 de enero de 2008

Mobile Media Converter

Mobile Media Converter es una aplicación muy interesante para convertir video y audio para reproductores MP3, MP4 y teléfonos móviles. Usa ffmpeg para convertir ficheros de audio MP3 / WAV / WMA a formato AMR (Adaptive Multi-Rate Codec, *.amr) y viceversa (AMR to MP3).

Además, puede convertir videos WMV (excepto WMV ver.9) y videos MPEG a 3GP y viceversa (MPEG a 3GP).

Existe una versión para windows y otra para linux.

El programa es muy sencillo de usar y permite seleccionar ficheros arrastrándolos a la aplicación.

Si queréis descargar la versión de linux, podéis hacerlo desde el siguiente enlace:

http://www.miksoft.net/products/mmc-lin.tar.gz

En cuanto a la versión de windows, podéis descargarla desde aquí:

http://www.miksoft.net/products/MMCsetup.exe

jueves, 24 de enero de 2008

Copias de seguridad incrementales con rsync

El sistema de copias de seguridad que uso en el instituto está basado en rsync (una herramienta disponible en linux). Para mí es uno de los mejores sistemas de copias de seguridad, sobre todo porque es muy fácil de implementar. Y lo mejor de todo, es que resulta muy sencillo buscar archivos en las copias de seguridad. Tan sólo hay que usar comandos que manejamos a diario, como p. ej. find.
Yo hago las copias de seguridad en una unidad nfs que tengo en un equipo que había en el instituto sin usar, pero se podrían hacer también en discos externos usb (muy baratos hoy en día) o firewire.
El script de copia de seguridad está sacado de una adaptación de Brian Hone de un script disponible en sync.samba.org.
Este script se ejecuta automáticamente de lunes a viernes a las 23:55. Para ello tengo una línea como la siguiente en el crontab del servidor:
# Copia de seguridad del servidor
55 23 * * 1,2,3,4,5 root /usr/sbin/hacerbackup.sh
Éste script hace copias de seguridad incrementales. Y funciona de la siguiente manera: La copia más actual se almacena en un directorio llamado main y las variaciones se almacenan en un directorio cuyo nombre es la fecha en que se hicieron las modificaciones.
Cosas que tenéis que configurar como mínimo para usarlo:
BACKUPDIR=directorio del que queremos hacer copia de seguridad. Yo tengo puesto el directorio / para hacer copia de seguridad de todo excepto lo que especifico en EXCLUDES
EXCLUDES=nombre del archivo en el que especificamos los directorios de los que no queremos hacer copia de seguridad. Creais este archivo y dentro ponéis la lista de directorios de los que no queréis hacer copias de seguridad, como por ejemplo /tmp, /usr...
ARCHIVEROOT=lugar donde almacenamos la copia de seguridad. Yo uso una máquina en la que tengo compartido un directorio por nfs. De este modo, las copias quedan almacenadas en un equipo diferente para poder recuperar datos si falla el servidor o si a alguien se le perdió algún archivo. Para que el directorio de backup de la otra máquina esté conectado tengo puesta la siguiente línea en el fstab del servidor: 172.19.144.16:/backup /backup nfs rw,hard,intr
Pego a continuación el script tal y como lo tengo montado en el servidor para hacer copias de seguridad del mismo:
 #!/bin/sh
#
# Script to do incremental rsync backups
# Adapted from script found on the rsync.samba.org
# Brian Hone 3/24/2002
# This script is freely distributed under the GPL
#
# Configure These Options
#
# mail address for status updates
# - This is used to email you a status report
#
# MAILADDR=adminies.valledeljerte@edu.juntaextremadura.net
#
# HOSTNAME
# - This is also used for reporting
#
HOSTNAME=valledeljerte3.valledeljerte3.ex

#
# directory to backup
# - This is the path to the directory you want to archive
#
BACKUPDIR=/

#
# excludes file - contains one wildcard pattern per line of files to exclude
# - This is a rsync exclude file. See the rsync man page and/or the
# example_exclude_file
#
EXCLUDES=/etc/excluirbackup

#
# root directory to for backup stuff
#
ARCHIVEROOT=/backup

#
# From here on out, you probably don't #
# want to change anything unless you #
# know what you're doing. #
#

# directory which holds our current datastore
CURRENT=main

# directory which we save incremental changes to
INCREMENTDIR=`date +%Y-%m-%d`

# options to pass to rsync
OPTIONS="--force --ignore-errors --delete --delete-excluded \
--exclude-from=$EXCLUDES --backup --backup-dir=$ARCHIVEROOT/$INCREMENTDIR -av"

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

# make sure our backup tree exists
install -d $ARCHIVEROOT/$CURRENT

# our actual rsyncing function
do_rsync()
{
rsync $OPTIONS $BACKUPDIR $ARCHIVEROOT/$CURRENT
}

# our post rsync accounting function
do_accounting()
{
echo "Backup Accounting for Day $INCREMENTDIR on $HOSTNAME:">/tmp/rsync_script_tmpfile
echo >> /tmp/rsync_script_tmpfile
echo "">>/tmp/rsync_script_tmpfile
du -s $ARCHIVEROOT/* >> /tmp/rsync_script_tmpfile
echo "Mail $MAILADDR -s $HOSTNAME Backup Report < /tmp/rsync_script_tmpfile" Mail $MAILADDR -s $HOSTNAME Backup Report < /tmp/rsync_script_tmpfile echo "rm /tmp/rsync_script_tmpfile" # rm /tmp/rsync_script_tmpfile }  # some error handling and/or run our backup and accounting if [ -f $EXCLUDES ]; then    if [ -d $BACKUPDIR ]; then       # now the actual transfer       do_rsync && do_accounting    else       echo "cant find $BACKUPDIR"; exit    fi else    echo "cant find $EXCLUDES"; exit fi  
Hay un artículo muy majo en el que Brian Hone habla de este sistema de copias de seguridad. Os recomiendo echarle un vistazo:
http://linuxfocus.org/Castellano/March2004/article326.shtml

miércoles, 16 de enero de 2008

CSATACOMBO: Una controladora Serial ATA & IDE

Tengo una máquina normalita con Linux en el centro funcionando como servidor de clonación, copias de seguridad, etc... cuyo disco duro se me estaba quedando pequeño.

Para cambiarlo, compramos un disco duro SATA de 500 Gb y una controladora Serial Ata & IDE CSATACOMBO, bastante económica.

He montado la controladora en el equipo, un Pentium 4 con un kernel 2.6.21.5-1-686 y me reconoce el disco duro sin problemas. Así que si buscáis una opción económica de montar un disco SATA en un equipo sin SATA, ésta controladora es una opción muy interesante.

lunes, 14 de enero de 2008

Universal XP drivers

Universal XP drivers es una excelente herramienta para técnicos informáticos que trabajen habitualmente con windows.

Es un CD ROM que contiene alrededor de unos 25.000 drivers de productos de marcas como por ejemplo Dell, HP, Compaq, IBM, Sony, Toshiba, Panasonic, Intel, 3Com, VIA, nVidia, ATI, SoundMax, etc...

Con este CD nos ahorraremos tener que estar buscando drivers en internet o en los CD's de los productos. Cuando el sistema nos pida instalar un driver, introducimos el CD y listo.

Un sitio para descargarlo:

http://www.taringa.net/posts/downloads/997682/Universal-XP-Drivers---25000-Drivers.html

WinUp: Actualización offline de windows

Como los administradores a veces también tenemos que pelear con máquinas windows, os voy a hablar de una herramienta interesante para actualizar las máquinas con XP de nuestra red.

Winup es un interesante paquete que contiene todos los parches oficiales de Microsoft para Windows XP.

Se distribuye como un programa ejecutable que nos evitará tener que descargar los parches de windows mediante Windows Update. Lo que es especialmente útil si administramos varios equipos, ya que nos ahorra tener que descargar cada parche en cada uno de ellos, con lo que ahorramos ancho de banda.

Además, nos permite instalar parches de Windows XP en máquinas sin Internet.
El requisito para instalar Winup es disponer de un Windows XP con el SP2.

La dirección para descargarlo:
http://sourceforge.net/projects/winup/

Si os parece interesante, podéis hacer un donativo.