El objetivo de este apartado es observar los cambios realizados en el sistema operativo MINIX 3 sin tener porque saber que ficheros hemos tocado. Para poder desarrollarlo me he tenido que devanar los sesos y recordar aquellas maravillosas clase de UNIX en primero de carrera.
Descargar Link: cambios_shx.pdf
1. Lo primero que he hecho ha sido bajarme una imagen nueva de la página de la asignatura.
2. Una vez que tenemos la imagen nueva, vamos a hacer una copia del directorio “/usr/src” y subdirectorios, pero necesitamos saber a dónde.
3. Para ver cómo está distribuido el sistema de ficheros utilizamos el commando:
#df
Observamos que en “/usr” hay un 99% de ocupación por lo que no nos vale, necesitamos por ejemplo utilizar “/home” para nuestro fin, ya que su índice de ocupación es del 11%.
4. Una vez que sabemos en donde vamos a realizar la copia, procedemos a ello:
#cp -r /usr/src /home
5. Con esta sencilla operación obtenemos en el directorio “/home” un subdirectorio “/home/src” en donde está todo el código fuente de MINIX 3.0.
6. Ahora viene la tediosa tarea de hacer la práctica 0, 1, 2 ó 3 (esta parte os la dejo a vosotros).
7. Una vez que hemos realizado la práctica correspondiente tenemos que ir al punto 8.
8. NOS LLEVAMOS LAS MANOS A LA CABEZA PORQUE NO SABEMOS COMO VER TODOS LOS CAMBIOS QUE HEMOS REALIZADO NI QUEREMOS RECORRERNOS TODO EL SISTEMA DE FICHEROS, PUES TRANQUILOS LA SOLUCIÓN ESTÁ EN EL PUNTO 9.
9. Como hemos realizado una copia de cada fichero en “/usr/src” en “/home” antes de haberlos modificado solo tenemos que comparar los 4343 ficheros que tiene “/usr/src” de uno a uno.
Este cálculo ha sido aproximado y realizado de la siguiente forma:
#find . | wc –l
10. Como eso es una tarea muy muy tediosa me he currado un script que hace lo siguiente.
11. Antes de nada indicar que mis conocimientos de UNIX y sus maravillosos comandos, es muy reducido, seguro que existe una forma más sencilla de hacerlo o con menos pasos, así que acepto sugerencias que no soy perfecto. Lo que hace básicamente este script es:
a. Borra la pantalla (para empezar no está mal ehhhh)
clear
b. Utilizo 2 ficheros temporales cada vez que se inicia el script comprueba si existen y si existen se borran.
if test -f fich_1.txt ; then
rm fich_1.txt ;
fi
if test -f fich_2.txt ; then
rm fich_2.txt ;
fi
c. Busco en el directorio actual, (por lo que me posiciono en “/usr/src”), todos los ficheros que sean FICHEROS y que no sean código objeto, la lista de ficheros resultantes se inserta en el fichero “fich_1.txt”.
find . \( ! -name '*.o' -a -type f \) > fich_1.txt ;
d. El contenido del fichero “fich_1.txt” es del tipo reseñado a continuación por lo que aplico el siguiente filtro.
./directorio/directorio/ficheroA
./directorio/directorio/ficheroB
./directorio/directorio/ficheroC
./directorio/directorio/ficheroD
./directorio/directorio/ficheroE
e. Extraigo de cada línea de “fich_1.txt” el “./” y lo sustituyo por “NADA”. Utilizo para ello el comando “sed”, donde busca con una expresión regular el comienzo de línea con “./” y lo cambia por “NADA”. El resultado lo envía a “fich_2.txt”.
sed 's/^\.//g' fich_1.txt > fich_2.txt ;
f. El contenido del fichero “fich_2.txt” es del tipo reseñado a continuación por lo que aplico el siguiente filtro.
directorio/directorio/ficheroA
directorio/directorio/ficheroA
directorio/directorio/ficheroA
directorio/directorio/ficheroA
directorio/directorio/ficheroA
g. A continuación utilizo “awk” ya que este comando trata cada “aparición” de texto en una línea como un campo por lo que voy a poder tratar cada línea como un campo.
awk -f rules.awk fich_2.txt > fich_1.txt
h. El comando anterior aplica el fichero de reglas para “rules.awk” a “fich_2.txt” y el resultado lo envía a “fich_1.txt”. El comando “awk” funciona de forma que se puede aplicar un filtro al inicio, otro a cada campo de cada línea y otro al final, en mi caso solo me interesa aplicar un filtro a cada campo de cada línea, pero como en cada línea solo hay un campo, sólo se hará una vez por línea. El contenido de “rules.awk” es el siguiente:
{
print "if test -f /home/src" $1 " ; then ";
print " diff /home/src" $1 " /usr/src" $1 " > /res/" ar[split($1,ar,"/")] ".diff ;" ;
print " echo -n + ;";
print "fi" ;
}
i. Las reglas para “awk” hacen los siguiente para cada línea, primero tenemos en cuenta que la línea 1 va a ser el campo 1, que se representa por $1. Lo que aquí estamos haciendo es simplemente escribir un texto NO ESTAMOS EJECUTANDO NADA. El campo $1 contiene una serie de directorio y termina en un fichero. Comprobamos si el fichero de la línea i-ésima existe, si es así escribe la sentencia:
“diff /home/src/[contenido_de_$1] /usr/src/[contenido_de_$1] > [fichero_de_$1].diff”
j. Después de escribir la línea anterior escribe un “echo” y finaliza el “if”.
k. Resultado:
If test -f /home/src/dir1/dir2/fich1 ; then
diff /home/src/dir1/dir2/fich1 /usr/src/dir1/dir2/fich1 > /res/fich1.diff ;
echo -n + ;
fi
l. Una vez que tenemos esta sentencia por cada línea del fichero, se envía todo esto a un nuevo fichero temporal.
m. Ejecutamos con “sh” ese fichero temporal, el resultado será que si existe el fichero hace la comparación y guarda el resultado en el directorio “/res” añadiéndole la extensión “.diff”. Confío en que no se modifique en 2 sitios diferentes 2 ficheros que tengan el mismo nombre y modificaciones diferentes.
n. Si todo va bien crea el directorio de resultados y ejecuta con “sh”.
if test ! -d /res ; then
mkdir /res ;
cd /res ;
fi
echo "Aplicando filtro [diff]..." ;
sh fich_1.txt
o. Como al hacer diff se puede crear ficheros de tamaño 0, con la siguiente sentencia los elimino.
find /res -size 0 -exec rm {} \;
p. Por último muestro con “ls” el total de ficheros que han cambiado.
ls -l /res
q. El resultado es lo que se muestra a continuación.
Fichero .awk: (solo he podido subirlo en PDF): rulesawk.pdf
Fichero .sh: (solo he podido subirlo en PDF): cambiossh.pdf
Espero que esto os sirva de ayuda o no, quien sabe.
Salu2