miércoles, 15 de noviembre de 2017

Script para parsear dhcpd.lease explicado en detalle

A continuación publico la traducción de este foro:
 https://www.linuxquestions.org/questions/programming-9/parse-dhcpd-leases-to-store-data-in-mysql-577693/page2.html
En el cual se explica con detalle cómo obtener información del archivo dhcpd.lease el cual es la base de datos del ics dhcp server.
 Primero enumeramos las 9 lineas del script para luego explicarlas en detalle una por una.

Script:
1) IP='([0-9]{1,3}\.){3}[0-9]{1,3}'

2) ST='(active|free)'

3) MAC='([0-9a-f]{2}:){5}[0-9a-f]{2}'



4) cat dhcpd.leases \

5) | sed 's,^ *,,' \

6) | egrep '^(lease|binding|hardware)' \

7) | egrep -o "$IP|$ST|$MAC" \

8) | sed -r 'N;N;s,\n(.*)\n(.*),\;\2\;\1,' \

9) > target.csv


Explicación detallada:
0) #! / bin / bash
=> shebang: par de caracteres #!
=> #! este archivo es un script
=> /bin/bash se usará bourne again shell

1) IP='([0-9]{1,3}\.){3}[0-9]{1,3}'
=> variable con expresión regular IP
=> expresión regular es una forma flexible para comparar cadenas de texto
=> con comillas; de lo contrario, se ve como una sola cadena
Principalmente, las comillas simples hacen que la cadena sea literal.
Más tarde, se usarán comillas dobles para permitir la sustitución de variables en una cadena.

Tenga en cuenta que '\' delante de '.', Asegura que cuando la variable se usa como expresión regular,
el '.' se interpretará literalmente, no como un comodín regex.
=> () agrupación, evalúa primero lo que está entre ()
=> [] condición
=> [0-9] llaves cuadradas para que coincida con un rango de caracteres, si los caracteres están separados por un guión
=> {1,3} {N, M} El elemento anterior se empareja al menos N veces, pero no más de M veces.
=> {3} {N} El elemento anterior coincide exactamente con N veces.

2) ST='(active|free)'
=> variable con dos estados posibles
=> | separa las palabras
Si nos preocupamos por todos los estados posibles, esto hubiera sido:
ST = '(libre | activo | expirado | liberado | abandonado | restablecido | copia de seguridad | reservado | bootp)'

3) MAC='([0-9a-f]{2}:){5}[0-9a-f]{2}'
=> variable con expresión regular MAC

4) cat dhcpd.leases \
=> Concatenar ARCHIVO, a salida estándar, o en tubería
Esta línea no es necesaria, el nombre del archivo fuente podría ser un argumento para el siguiente comando. Lo hice así por claridad.
Del mismo modo, la tubería podría haber sido colocada en una línea larga, puse cada
pipe en una línea separada para mayor claridad.
Nota: la '\' en los extremos de estas líneas funciona como caracteres de continuación,

siempre y cuando
él realmente sea el ÚLTIMO caracter en la línea.
Finalmente, elijo la tubería, '|', al comienzo de la siguiente línea,

en lugar del final de la anterior para
mejor estética, claridad y conveniencia de destacar las piezas durante la prueba.
    Código:
      gato ... \
     |  sed ... \ 
    vs.
    Código:
      gato ... |
     sed ... | 




5) | sed 's,^ *,,' \
Este es un preprocesador que garantiza que el egrep en la línea siguiente funcionará correctamente.
=> El Stream EDitor se utiliza para realizar transformaciones básicas en la lectura de texto de un archivo o un conducto. El resultado se envía a la salida estándar.
=> s Buscar y reemplazar texto (sustitución)
=> ^ coincide con una nueva línea
coincide con el comienzo de una línea
=> * El elemento anterior , un espacio, se emparejará cero o más veces
=> ,,
La forma "normal" para una expresión regular de sustitución es "s ///",
cualquier caracter puede ser usado -- la 1ra cosa después de 's' se conviert
e en el delimitador.
La persona que comenzó a enseñarme
sed prefirió las comas por razones estéticas:
- Compare "s/\/\/\//\/\//"
con "s,///,//,"…

6) | egrep '^(lease|binding|hardware)' \
=> egrep busca un patrón que es una expresión regular extendida
=> ^ coincide con todo, excepto un espacio
No en este contexto, el '^' coincide con la cadena nula al comienzo de una línea.
=> ^ en este caso coincide con el lease sugerido, enlace, hardware
Solo coincide con las palabras de destino si ocurren al comienzo de la línea,
esta es la razón por la cual
sencillo sed anterior es necesario.

7) | egrep -o "$IP|$ST|$MAC" \
=> -o Muestra solo la parte que coincide, de una línea coincidente
Una de las mejores banderas que conozco


8) | sed -r 'N;N;s,\n(.*)\n(.*),\;\2\;\1,' \
=> -r usa expresiones regulares en el script
Desde la página man: "usar expresiones regulares extendidas en el script".
La distinción es importante: lo hace actuar como egrep ,
de lo contrario, los metacaracteres "() {}" tendrían que ser escapados, es decir, precedidos por un '\'.

=> N no imprimir
'N' agrega la siguiente línea de entrada al espacio del patrón.
"-n" es la bandera de no imprimir.
=> \ n nuevo carácter de línea

9) > target.csv
=>> salida a target.csv

Como dije antes, este script es frágil.
Es frágil porque no intenta validar su entrada; entonces, si cualquiera de mis suposiciones es incorrecta, puede dar resultados impredecibles. Siempre que se use en el contexto para el que fue escrito, debería funcionar como se esperaba.

No hay comentarios: