Linux Standard Base
La Base Estándar para Linux (Linux Standard Base, abreviado LSB), es un proyecto conjunto de varias Distribuciones de Linux bajo la estructura organizativa del Free Standards Group con el objeto de crear y normalizar la estructura interna de los sistemas operativos derivados de Linux. La LSB está basada en la Especificación POSIX, la Especificación Única de UNIX (Single UNIX Specification) y en varios otros estándares abiertos, aunque extiende éstos en ciertas áreas.
De acuerdo a la definición de la propia LSB:
- El objetivo de la LSB es desarrollar y promover un conjunto de estándares que aumentarán la compatibilidad entre las distribuciones de Linux y permitirán que los programas de aplicación puedan ser ejecutados en cualquier sistema que se adhiera a ella. Además, la LSB ayudará a coordinar esfuerzos tendentes a reclutar productores y proveedores de programas que creen productos originales para Linux o adaptaciones de productos existentes.
Mediante un proceso de certificación es posible obtener la conformidad a la LSB de un producto. Dicha certificación la lleva a cabo el Open Group en colaboración con el Free Standards Group (Grupo de Estándares Libres).
Como ejemplo, la LSB específica: bibliotecas estándar, un conjunto de órdenes y utilerías que extienden el estándar POSIX, la estructura jerárquica del sistema de archivos, los niveles de ejecución, y varias extensiones al sistema gráfico X Window.
Puntos de montaje
Aparte del sistema de ficheros principal (/) y de sus posibles divisiones en particiones extras (/usr /var, /tmp, /home), cabe tener en cuenta la posibilidad de dejar puntos de montaje preparados para el montaje de otros sistemas de ficheros, ya sea particiones de disco u otros dispositivos de almacenamiento.
En las máquinas en que GNU/Linux comparte la partición con otros sistemas operativos, mediante algún sistema de arranque (LILO o GRUB), pueden existir varias particiones asignadas a los diferentes operativos. Muchas veces es interesante compartir datos con estos sistemas, ya sea para leer sus ficheros o modificarlos. A diferencia de otros sistemas (que sólo tienen en cuenta sus propios datos y sistemas de ficheros, y en los cuales en algunas versiones no se soportan algunos de sus propios sistemas de ficheros), GNU/Linux es capaz de tratar, como hemos visto, con una cantidad enorme de sistemas de ficheros de diferentes operativos y poder compartir la información.
Explicación
Si en los PC personales hemos instalado GNU/Linux, seguramente encontraremos más de un operativo, por ejemplo, otra versión de GNU/Linux con ext2 o ext3 de sistema de ficheros y otros. Por ejemplo, sistema de ficheros FAT, FAT32 (o vfat para Linux) o NTFS (ntfs para Linux).
Nuestro sistema GNU/Linux puede leer datos (o sea ficheros y directorios) de todos estos sistemas de ficheros y escribir en la mayoría de ellos.
En el caso de NTFS, hasta ciertos momentos, existieron problemas en la escritura que se encontraba en forma experimental en la mayoría dedrivers de kernel. Esto se debía principalmente a las diferentes versiones que van apareciendo del sistema de ficheros, ya que existen dos versiones principales llamadas NTFS y NTFS2, y algunas extensiones como los llamados volúmenes dinámicos, o los sistemas de ficheros encriptados. Acceder con según que drivers presentaba ciertas incompatibilidades, que podrían causar corrupciones de datos o errores en el sistema de ficheros.
Gracias a FUSE (un módulo integrado en el kernel a partir de la versión 2.6.11) se ha permitido un desarrollo más flexible de sistemas de ficheros, directamente en espacio de usuario (de hecho FUSE actúa como un “puente” entre las peticiones del kernel, y el acceso que se hace desde el driver).
Gracias a las posibilidades de FUSE, se tiene un soporte más o menos completo de NTFS, en especial desde la aparición del driver (basado en FUSE) ntfs-3g (http://www.ntfs-3g.org), y la combinación con las utilidades ntfsprogs.
Para que se puedan leer o escribir los datos, la partición tiene que estar disponible dentro de nuestro sistema de ficheros raíz (/). Por lo tanto, hay que llevar a cabo un proceso de "montaje" del sistema de ficheros en algún punto de nuestro árbol de directorios. Se seguirá el mismo proceso si se trata de un dispositivo de almacenamiento.
Dependiendo de la distribución, se usan unos u otros, o también los podemos crear nosotros. Normalmente suelen existir o bien como subdirectorios de la raíz, por ejemplo /cdrom, /win, /floppy, o bien son subdirectorios dentro de /mnt, el punto estándar de montaje (aparecen como /mnt/cdrom, /mnt/floppy...), o el directorio /media preferido últimamente por las distribuciones. Según el estandard FHS, /mnt se debería usar para montajes temporales de sistemas de archivo, mientras /media se utilizaría para montar dispositivos removibles.
El proceso de montaje se realiza mediante la orden mount con el siguiente formato:
mount -t filesystem-type device mount-point
El tipo de sistema de ficheros puede ser:
- msdos (fat)
- vfat (fat32)
- ntfs (ntfs)
- iso9660 (para cdrom)
El dispositivo es la entrada correspondiente en el directorio /dev a la localización del dispositivo:
- Los IDE tenían /dev/hdxy donde:
- x es a (1 master), b (1 slave), c (2 master) o d (2 slave)
- y es el número de partición
- Los SCSI son /dev/sdx donde:
- x es a,b,c,d ... (según el ID SCSI asociado 0,1,2,3,4 ...).
Ejemplos
- Montar el CD-ROM (si es el IDE que está en el segundo IDE de forma máster) en el punto /mnt/cdrom.
mount -t iso9660 /dev/hdc /mnt/cdrom
- Montar el CD-ROM; /dev/cdrom se usa como sinónimo (es un enlace) del dispositivo donde está conectado:
mount -t iso9660 /dev/cdrom /mnt/cdrom
- Montar el disquete /dev/fd0H1440. Sería la disquetera A en alta densidad (1.44 MB), también puede usarse /dev/fd0:
mount -t vfat /dev/fd0H1440 /mnt/floppy
Si estas particiones son más o menos estables en el sistema (o sea, no cambian frecuentemente) y las queremos utilizar, lo mejor será incluir los montajes para que se hagan en tiempo de ejecución, al iniciar el sistema, mediante la configuración del fichero /etc/fstab:
Archivo: /etc/fstab
# /etc/fstab: Información estática del sistema de ficheros
#
#
/dev/hda2 / ext3 errors = remount,ro 0 1
/dev/hdb3 none swap sw 0 0
proc /proc proc defaults 0 0
/dev/fd0 /floppy auto user,noauto 0 0
/dev/cdrom /cdrom iso9660 ro,user,noauto 0 0
/dev/sdb1 /mnt/usb vfat user,noauto 0 0
Por ejemplo, esta configuración incluye algunos de los sistemas estándar, como la raíz en /dev/hda2, la partición de swap que está en hdb3, el sistema proc (que utiliza el kernel para guardar su información). Y el disquete, el CD-ROM, y en este caso un disco USB de tipo Flash (que se detecta como un dispositivo SCSI). En algunos casos, se especifica auto como tipo de sistema de ficheros. Esto permite que se autodetecte el sistema de ficheros. Si se conoce, es mejor indicarlo en la configuración, y por otra parte, el noauto en las opciones permite que no sea montado de forma automática siempre, sino bajo petición (o acceso).
Si tenemos esta información en el fichero, el proceso de montaje se simplifica mucho, ya que se hará o bien en ejecución, en arranque, o bien bajo demanda (para los noauto). Y puede hacerse ahora simplemente pidiendo que se monte el punto de montaje o el dispositivo:
mount /mnt/cdrom
mount /dev/fd0
dado que el sistema ya tiene el resto de la información.
El proceso contrario, el desmontaje, es bastante sencillo. Tan sólo hay que ejecutar la orden umount con punto o dispositivo:
umount /mnt/cdrom
umount /dev/fd0
En el caso de medios extraíbles, tipo CD-ROM (u otros), puede usarse eject para la extracción del soporte físico:
eject /dev/cdrom
o, en este caso, sólo:
eject
Las órdenes mount y umount montan o desmontan todos los sistemas disponibles. En el fichero /etc/mtab se mantiene una lista de los sistemas montados en un momento concreto, que se puede consultar utilizando:
mount
Procesamiento y edición de texto
AWK
AWK es un lenguaje de programación que fue diseñado con el objetivo de procesar datos basados sobre texto y una de las primeras herramientas en aparecer en Unix. Su nombre deriva de la primera letra de los apellidos de sus autores Alfred Aho, Peter Weinberger y Brian Kernighan.
Utiliza listas en un índice ordenado por cadenas clave (listas asociativas) y expresiones regulares. Es un lenguaje ampliamente utilizado para la programación de guiones ejecutables pues añade funcionalidad a las tuberías en los sistemas operativos tipo POSIX. Está incluido en las instalaciones básicas de prácticamente todas las distribuciones de GNU/Linux.
Estructura de los programas escritos en AWK
La orden awk utiliza un fichero o emisión de ordenes y un fichero o emisión de entrada. El primero indica como procesar al segundo. El fichero de entrada es por lo general texto con algún formato que puede ser un fichero o bien la salida de otro mandato.
La sintaxis general utilizada para el mandato awk sigue el siguiente patrón:
awk 'expresión-regular { orden }'
Cuando se utiliza el mandato, éste examina el fichero de entrada y ejecuta la orden cuando encuentra la expresión regular especificada.
El siguiente modelo ejecutaría la orden al inicio del programa y antes de que sean procesados los datos del fichero de entrada:
awk 'BEGIN { orden }'
El siguiente modelo ejecutaría la orden al final del programa y después de que sean procesados los datos del fichero de entrada:
awk 'BEGIN { orden }'
El siguiente modelo ejecutaría la orden por cada una de las líneas del fichero de entrada:
awk '{ orden }'
Ejemplos de uso de AWK
A continuación vamos a ir realizando ejemplos con esta orden, mientras se van comentando diversas características.
- Especificar que al inicio se imprima en la salida la frase "Hola mundo" y terminar el procesamiento:
awk 'BEGIN { print "Hola mundo"; exit }' Hola mundo
Vamos a utilizar un fichero prueba.txt para las pruebas siguientes:
echo -e "Columna1\tColumna2\tColumna3\tColumna4\n" > ejemplo.txt
cat ejemplo.txt Columna1 Columna2 Columna3 Columna4
cat ejemplo.txt Columna1 Columna2 Columna3 Columna4
- Mostrar únicamente la columna 1 y la columna 3:
awk '{ print $1, $3}' ejemplo.txt Columna1 Columna3
- Mostrar únicamente la columna 3 y la columna 1 y en ese orden:
awk '{ print $3, $1}' ejemplo.txt Columna3 Columna1
Editamos los datos de un fichero ejemplo.txt del siguiente modo:
echo -e "Dato1\tDato2\tDato3\tDato4\n" >> ejemplo.txt
echo -e "Dato5\tDato6\tDato7\tDato8\n" >> ejemplo.txt
echo -e "Dato9\tDato10\tDato11\tDato4\12" >> ejemplo.txt
echo -e "Dato5\tDato6\tDato7\tDato8\n" >> ejemplo.txt
echo -e "Dato9\tDato10\tDato11\tDato4\12" >> ejemplo.txt
cat ejemplo.txt Columna1 Columna2 Columna3 Columna4
Dato1 Dato2 Dato3 Dato4
Dato5 Dato6 Dato7 Dato8
Dato9 Dato10 Dato11 Dato4
Dato1 Dato2 Dato3 Dato4
Dato5 Dato6 Dato7 Dato8
Dato9 Dato10 Dato11 Dato4
- Mostrar la columna 1 y la columna 3 del siguiente modo:
awk '{ print $1, $3}' ejemplo.txt Columna1 Columna3
Dato1 Dato3
Dato5 Dato7
Dato9 Dato11
Dato1 Dato3
Dato5 Dato7
Dato9 Dato11
- Mostrar solo la línea cuya columna contenga la expresión regular Dato5:
awk '/Dato5/ { print }' ejemplo.txt Dato5 Dato6 Dato7 Dato8
- Mostrar solo la línea cuya columna contenga la expresión regular Dato5 y además las columnas 1 y 4:
awk '/Dato5/ { print $1, $4}' ejemplo.txt Dato5 Dato8
- Mostrar solo las líneas con más de 35 caracteres del fichero /etc/crontab:
awk 'length > 35' /etc/crontab 01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
- Mostrar solo las líneas con menos de 35 caracteres en el fichero /etc/crontab:
awk 'length < 35' /etc/crontab SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
Creamos un fichero usuario.txt con el siguiente contenido:
Archivo: usuario.txt
Fulano AlgoCalle Mengana 123
Colonia Perengana
Ciudad de Zutano, C.P. 123456
Para que reconozca cada línea como un registro completo, en lugar de considerar cada palabra como una columna, se utiliza 'BEGIN { FS="\n" ; RS=""}', donde:
- el valor de FS (Field Separator o separador de campo) se establece como un retorno de carro
- el valor de RS (Record Separator o separador de registro) se establece como una línea vacía
- Imprimir los valores de cada registro (cada línea) separados por una coma y un espacio:
awk 'BEGIN { FS="\n"; RS="" } { print $1 ", " $2 ", " $3 ", " $4 }' usuario.txt Fulano Algo, Calle Mengana 123, Colonia Perengana, Ciudad de Zutano, C.P. 123456
Información: El mandato awk puede contar líneas, palabras y caracteres.
- Establecer que el valor de w sea igual al número de campos (New Field o NF), c sea igual la longitud de cada campo, e imprimir el número de campos, el valor de w y el valor de c:
awk '{ w += NF; c += length} \
END { print \
"Campos: " NR , "\nPalabras: " w, "\nCaracteres: " c }' \
usuario.txt Campos: 4
Palabras: 12
Caracteres: 74
END { print \
"Campos: " NR , "\nPalabras: " w, "\nCaracteres: " c }' \
usuario.txt Campos: 4
Palabras: 12
Caracteres: 74
Generamos el fichero numeros.txt con el siguiente contenido, donde las columnas serán separadas por un tabulador:
Archivo: numeros.txt
1 2 3 4
5 6 7 8
9 10 11 12
Información: El mandato awk puede realizar operaciones matemáticas.
- Establecer que s es igual a la suma del valor de los campos de la primera columna del fichero numeros.txt, e imprimir el valor de s:
awk '{ s += $1 } END { print s }' numeros.txt 15
- Lo mismo, pero con los valores de la columna 2:
awk '{ s += $2 } END { print s }' numeros.txt 18
- Contar la frecuencia de palabras (para ello se establece que el valor para FS sea igual a expresiones regulares que van desde la a a la z y desde la A a la Z, se establece que el valor de la variable i es igual a 1 y menor al número de campos):
awk 'BEGIN { FS="[^a-zA-Z]+"} \
{ for (i=1; i<=NF; i++) words[tolower($i)]++ } \
END { for (i in words) print i, words[i] }' /etc/crontab 7
bin 3
run 5
etc 4
sbin 3
bash 1
weekly 1
daily 1
cron 4
usr 2
path 1
shell 1
parts 5
home 1
mailto 1
monthly 1
hourly 1
root 6
{ for (i=1; i<=NF; i++) words[tolower($i)]++ } \
END { for (i in words) print i, words[i] }' /etc/crontab 7
bin 3
run 5
etc 4
sbin 3
bash 1
weekly 1
daily 1
cron 4
usr 2
path 1
shell 1
parts 5
home 1
mailto 1
monthly 1
hourly 1
root 6
Sed
Sed es un editor de emisiones (stream editor) utilizado para el procesamiento de texto en ficheros. Utiliza un lenguaje de programación para realizar transformaciones en una emisión de datos leyendo línea por línea de estos. Fue desarrollado entre 1973 y 1974 por Lee E. McMahon de Bell Labs. Está incluido en las instalaciones básicas de prácticamente todas las distribuciones de GNU/Linux.
Ejemplos de uso de sed
Utilice vi o vim para crear el ficheroprueba.txt
:
vi prueba.txt
Ingrese el siguiente contenido y salga de
vi
:
Archivo: prueba.txt
Monstruo Espagueti Volador
Calle de los espagnósticos 123
Barrio de Espagnostia
Ciudad Pastafari, C.P. 123456Calle de los espagnósticos 123
Barrio de Espagnostia
cat
sobre el fichero, visualizará tal cual el contenido de prueba.txt como fue ingresado en vi
.
cat prueba.txt
Si se quiere convertir a doble espacio la salida del fichero prueba.txt, utilice el siguiente mandato:
sed G prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Para guardar esta salida en el fichero usuario2.txt, utilice lo siguiente:
sed G prueba.txt > usuario2.txt
Si se quiere convertir a doble espacio la salida del fichero prueba.txt, utilice el siguiente mandato:
sed 'G;G' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Para guardar esta salida en el fichero usuario3.txt, utilice lo siguiente:
sed 'G;G' prueba.txt > usuario3.txt
El contenido de usuario3.txt tendrá triple espacio de separación. Si se desea convertir un fichero a doble espacio, pero que no haya más de una línea vacía entre cada línea con datos, se utiliza lo siguiente:
sed '/^$/d;G' usuario3.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Si se desea eliminar el doble espacio del fichero usuario2.txt, se utiliza lo siguiente:
sed 'n;d' usuario2.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Si se quiere agregar una línea en blanco arriba de toda línea que contenga la expresión regular <>, se utiliza lo siguiente:
sed '/espag/{x;p;x;}' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Si se quiere agregar una línea en blanco debajo de toda línea que contenga la expresión regular "3", se utiliza lo siguiente:
sed '/3/G' prueba.txt
Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Si se quiere agregar una línea en blanco arriba y debajo de toda línea que contenga la expresión regular "3", se utiliza lo siguiente:
sed '/3/{x;p;x;G;}' prueba.txt
Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
Para reemplazar texto se utiliza el modelo 's/texto/nuevo-texto/' donde texto puede ser también una expresión regular. En el siguiente ejemplo se reemplazarán las incidencias del número por el número 9:
sed 's/3/9/g' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 129 Barrio de Espagnostia Ciudad Pastafari, C.P. 129456
En el siguiente ejemplo se reemplazan los espacios por tabuladores a todo lo largo de todas las líneas:
sed 's/\ /\t/g' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 129 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
En el siguiente ejemplo se reemplazan solo el primer espacio de cada línea por un tabulador:
sed 's/\ /\t/' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 129 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
La siguiente línea añade 5 espacios al inicio de cada línea:
sed 's/^/ /' prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
El siguiente mandato solo imprime la primera línea del fichero prueba.txt:
sed q prueba.txt Monstruo Espagueti Volador
El siguiente mandato solo imprime las primeras dos líneas del fichero prueba.txt:
sed 2q prueba.txt Monstruo Espagueti Volador Calle de los espagnósticos 123
El siguiente mandato solo muestra las últimas tres líneas del fichero prueba.txt:
sed -e :a -e '$q;N;4,$D;ba' prueba.txt Calle de los espagnósticos 123 Barrio de Espagnostia Ciudad Pastafari, C.P. 123456
El siguiente mandato solo mostrará las líneas que incluyen "3":
sed '/3/!d' prueba.txt Calle de los espagnósticos 123 Ciudad Pastafari, C.P. 123456
El siguiente mandato solo mostrará las líneas que no incluyen 3:
sed '/3/d' prueba.txt Monstruo Espagueti Volador Barrio de Espagnostia
El siguiente mandato pide mostrar la linea que está inmediatamente después de la expresión Fulano, pero no la línea en si que incluye Fulano:
sed -n '/Fulano/{n;p;}' prueba.txt Calle de los espagnósticos 123
El siguiente mandato pide mostrar la linea que está inmediatamente antes de la expresión Calle, pero no la línea en si que incluye Calle:
sed -n '/Calle/{g;1!p;};h' prueba.txt Monstruo Espagueti Volador