Este no blog no va a ser actualizado más, me he mudado a http://conocimientoabierto.es

lunes, 26 de marzo de 2007

Sonido y múltiples usuarios

Antes de entrar en el título del post, me gustaría repasar una de las primeras cosas que se aprenden cuando se empieza a profundizar un poco en GNU/Linux, cualquier elemento del sistema es tratado como si fuese un fichero. Es decir, desde la foto que hemos descargado de la cámara hasta nuestra tarjeta de sonido pasando por el disco duro tienen una representación (un nombre) dentro del sistema de ficheros.

Comprender La estructura del árbol de directorios no es necesario en la práctica, pero nos ayudará a entendernos mejor con el ordenador. Esta estructura dicta por tanto donde debería ir colocado cada elemento del sistema. Nuestros archivos personales estarán en alguna subcarpeta de /home mientras que nuestro disco duro será representado por /dev/hda.

Nuestra tarjeta de sonido estará representada mediante los ficheros /dev/dsp o /dev/audio, que por supuesto tendrán establecidos unos determinados permisos y pertenecerán a un determinado usuario y grupo. Lo que viene a continuación está comprobado en una Mandriva 2007 pero entiendo que será extrapolable a la mayoría de distribuciones de Linux.

crw-rw---- 1 fran audio 14, 4 mar 26 10:37 /dev/audio
crw-rw---- 1 fran audio 14, 3 mar 26 10:37 /dev/dsp


Cuando nos identificamos como un determinado usuario el sistema define como propietario de /dev/audio al usuario con el que hemos identificado, el grupo audio es creado durante la instalación del sistema operativo. Si estando identificados como usuario1 lanzamos algún proceso (mediante el comando su por ejemplo) como usuario2 que requiera usar la tarjeta de sonido habrá un error puesto que el segundo usuario no tendrá los permisos adecuados para escribir en el fichero que representa a la tarjeta de sonido.

La solución más sencilla y elegante (si el grupo audio existe) será agregar a todos los usuarios que nos interese a ese grupo. Podemos hacerlo mediante la interfaz gráfica (en Mandriva Sistema->Configuración->Otro->Administrar Usuarios o abriendo un terminal de root y tecleando
gpasswd -a fran audio

Nuestra otra opción es aplicar permisos de escritura y lectura para todos sobre esos ficheros chmod a+r a+w /dev/audio

lunes, 12 de marzo de 2007

Cambiar permisos de forma recursiva y selectiva

Por culpa de un modem con drivers propietarios (y mi ineptitud para instalar unos libres) llevaba unos 6 meses usando Windows. En otro artículo hablaré de mi odisea particular con los drivers, pero en este quiero hablar de uno de los problemas que nos asaltan cuando migramos de sistema operativo, traspasar los datos que tengamos almacenados en el antiguo sistema al nuevo.

Cambiar de Windows a Linux implica cambiar de sistema de ficheros. Si somos un poco meticulosos enseguida nos damos cuenta de que no vale simplemente con copiar y pegar puesto que los permisos de los ficheros que hayamos copiado quedaran descolocados. El esquema de permisos será algo como esto -r-xr-xr-x, es decir, sin permisos para poder modificar los ficheros ya creados y todos con la posibilidad de ser ejecutados. Además todos los usuarios del sistema pueden leer los datos del resto de usuario, con los peligros de seguridad que ello conlleva.

Migrar entre sistemas Unix (o entre distintas distribuciones de GNU/Linux) no nos dará esta clase de problemas a no ser que no copiemos los datos de una partición del disco duro a otra, sino que lo que hagamos sea hacer una copia de los ficheros a DVD y de ahí de nuevo al disco duro. En este caso, también aplicable a cuando hacemos copias de seguridad, lo más sencillo es empaquetar nuestros datos en un archivo comprimido mediante la utilidad tar pasándole las opciones adecuadas en la línea de comandos para indicarle que preserve los permisos originales de los ficheros.

Para crear la copia.
$tar --create --bzip2 --file=copia.tar.bz2 /home/fran/Documentos

Para restaurarla
$tar --extract --bzip2 --atime-preserve --same-permissions --file=copia.tar.bz2

Las opciones aquí empleadas y más información pueden encontrarse como siempre en la ayuda del programa
$man tar

Lo que pretendía explicar era de todas formas otra cosa. En el momento en que tenemos los ficheros copiados y con los permisos establecidos de manera no adecuada debemos tirar del comando chmod para cambiarlos. Para cambiar de manera recursiva los permisos de todos los ficheros y directorios a partir del que elijamos usaremos:
$chmod -R 0777

El probema es que chmod no discrimina tipos de archivo, estaremos asignando los mismos permisos a directorios, documentos de texto, ficheros que nos gustaria que fuesen de solo lectura como fotos, etc. La solución nos la da el comando find. Las posibilidades del comando find son muy amplias aunque para nuestro objetivo expongo aquí las más interesantes:
  • -type d : Devuelve los nombres de los directorios
  • ! : Niega la siguiente expresión. Así, ! -type d Devuelve los nombres de los ficheros no directorios
  • -iname patron : Devuelve los nombres de ficheros (sin distinguir mayúsculas y minúsculas) que coinciden con un determinado patrón, podemos usar los comodines * y ?
  • -iregex patron : Como el anterior pero patrón es una expresión regular.
  • -exec comando {} \; : Ejecuta el comando comando. {} Representa los nombres de archivo devueltos por find, es decir que ejecutamos el comando para cada fichero devuelto por find. \; Es usado por la shell para reconocer el final del comando.

Así para el caso más habitual en que deseamos otorgar permisos de lectura, escritura y ejecución para directorios, y de lectura y escritura para el resto de archivos (y ninguno para el resto de usuarios) los comandos serían:
find directorio -type d -exec chmod 0700 {} \;
find directorio ! -type d -exec chmod 0600 {} \;


Para aquellos con pocas ganas de jugar con los comandos, he escrito un pequeño script. Para ejecutarlo sólo hay que copiar el código y guardarlo en un fichero de texto de nombre cambiar_permisos.sh (por ejemplo). Abrir una consola y escribir:
$sh cambiar_permisos.sh directorio
En el script se distinguen tres tipos de archivos:
  • ficheros con las extensiones .*pdf .*jpg .*jpeg .*bmp .*png .*gif .*avi .*mpg .*mpeg .*mp3 .*ogg a los que se asignan los permisos 0400
  • directorios, a los que se asignan los permisos 0700
  • resto de ficheros, a los que se asignan los permisos 0600


#!/bin/sh

# Francisco Puga Alonso.
# 10/03/2007 v 0.2

# Este software se distribuye sin ninguna garantía.
# El autor no se hace responsable de los posibles daños de su uso
# Este software pertenece al dominio público
# Para consultar la ayuda del script ejecute ./cambiar_permisos -h

# Este script cambia los permisos de los ficheros y directorios a partir del
# directario de entrada que nosotros le indiquemos. A la hora de cambiar los
# permisos, asigna permisos separados a directorios, ficheros de sólo lectura
# y resto de ficheros. Si quiere saber que se consideran ficheros de sólo
# ejecute ./cambiar_permisos -h o consulte el valor de la variable EXT_READ

# Se comprueba que el directorio origen existe, pero no comprueba que tengamos
# los permisos adecuados para cambiarlos


#Ficheros considerados de sólo lectura.
EXT_READ=".*pdf .*jpg .*jpeg .*bmp .*png .*gif .*avi .*mpg .*mpeg .*mp3 .*ogg"
#EXT_REGEX contiene la expresión regular que identificará estos ficheros
EXT_REGEX=".*pdf\|.*jpg\|.*jpeg\|.*bmp\|.*png\|.*gif\|.*avi\|.*mpg\|.*mpeg\|.*mp3\|.*ogg"

#Permisos por defecto aplicados a los distintos tipos de fichero considerados
PDIRS="0700"
PREAD="0400"
POTHERS="0600"
DIR="/dev/null"


ayuda() {
#Imprime la información de ayuda
echo "Usage: $0 [-d ] [-r ] [-o ]"
echo "-d :: Permisos aplicados a directorios y subdirectorios. Por defecto 0700"
echo -e "-r :: Permisos aplicados a los siguientes formatos de archivo "
echo -e "(Por defecto 0400):\n$EXT_READ"
echo "-o :: Permisos aplicados al resto de ficheros. Por defecto 0600"
echo "-h :: Imprime esta ayuda"
exit
}


if [ $# = "0" ] ; then
echo "Debe especificar un directorio. Use . para referirse al directorio actual"
ayuda $0

else
if ! [ -d $1 ] ; then
echo "El primer parametro debe ser un directorio"
ayuda $0
else DIR="$1"
fi

shift

while (( $# )) ; do
case $1 in
-d ) PDIRS="$1";;
-r ) PREAD="$1";;
-o ) POTHERS="$1";;
-h ) ayuda $0 ;;
* ) echo "Opción Incorrecta" ; ayuda $0 ;;
esac
shift
done
fi


find "$DIR" -mount -type d -exec chmod "$PDIRS" {} \;
find "$DIR" -mount ! -type d -and -iregex "$EXT_NOW" -exec chmod "$PREAD" {} \;
find "$DIR" -mount ! -type d -and ! -iregex "$EXT_NOW" -exec chmod "$POTHERS" {} \;

El código no me ha quedado demasiado bien maquetado pero aún tengo que mejorar mi CSS. Para la realización de este script me he inspirado en este post de Javier Sancho

jueves, 8 de marzo de 2007

Motivos

El mundo es un lugar complejo. Mientras 1200 millones de personas carecen de agua potable unos cuantos cientos o miles pueden comer en Londres y llegar a París a bordo de su jet privado a tiempo de ver iluminarse a la Torre Eiffel.

Las causas de esta desigualdad son muchas. Este blog surge con la finalidad de hablar de algunas de ellas, especialmente de aquellas relacionadas con la llamada Sociedad de la Información, el flujo libre de conocimientos y la tecnología. De muy diversas formas se puede abordar esta tarea, por mi parte trataré de mezclar los artículos de opinión (espero que debidamente justificada) con artículos un poco más técnicos y pequeñas recetas que demuestren la sencillez de uso y las increíbles capacidades del sistema operativo libre más extendido, GNU/Linux.

No soy experto en nada por tanto lo que aquí publique no debe ser tomado como verdades absolutas, espero que todo aquel que esté en contra (o a favor) de lo que diga use los comentarios para manifestar su postura. Esa es la grandeza de la web, todo el mundo puede ser leído.