Buscar este blog

Mostrando entradas con la etiqueta script. Mostrar todas las entradas
Mostrando entradas con la etiqueta script. Mostrar todas las entradas

martes, 9 de abril de 2013

Eliminar comentarios en archivos de configuración con grep.

Si es habitual para nosotros trabajar con archivos de configuración en linux o similares, seguramente nos habremos encontrado con algunos muy bien documentados con comentarios.
Esto es muy útil para la inicialización de servicios, pero a la hora de resolver problemas recorrer un archivo con 3000 lineas no es práctico.

Buscando encontré esto que soluciona el problema pero tiene un defecto.

Por ejemplo, trabajando con Squid: /etc/squid/squid.conf
Si hacemos
grep "#" /etc/squid/squid.conf
Nos mostrará en pantalla las lineas del archivo que posean el carácter #.
Ahora si invertimos la búsqueda con -v
grep -v "#" /etc/squid/squid.conf
Mostrará las ubicaciones donde no se encuentre el mismo, incluyendo lineas vacías, lo que "queda feo".

El autor propone limpiar la salida con grep -v "#" /etc/squid/squid.conf | sed -e '/^$/d' que cumple y deja solo las lineas que buscamos con el #.

Prestando un poco de atención, y buscando en Internet surgen 2 cosas:

  1. Si la linea tiene un # en cualquier lugar distinto del inicio no será mostrada, esto es un problema.
  2. NO necesitamos sed, grep es lo suficientemente flexible como para mostrarnos lo que queremos ver.

Ambas se solucionan con esto
grep '^[^#]' /etc/squid/squid.conf

¿Y esto, para que sirve?
En particular lo utilizo para limpiar los archivos y guardar solo las variables y configuraciones activas.
Según el ejemplo anterior 
grep '^[^#]' /etc/squid/squid.conf > squid.conf.limpio
Genera una copia del archivo solo con lo importante y listo para guardar.
Otra opción es crear un script de bash por si nos olvidamos como es el comando; generamos un  documento de texto, lo llamamos sincom.sh y pegamos lo siguiente dentro :

#!/bin/bash
#Uso
#./sincomen.sh archivo_con_comentarios archivo_destino

grep '^[^#]' $1 > $2

Guardamos y le damos permisos de ejecución con chmod +x sincom.sh. 
¡Listo!, ejecutando ./sincom.sh archivo_comentado archivo_limpio  tenemos automatizada la tarea.

Espero sirva.

viernes, 2 de marzo de 2012

Como volver legible el timestamp de dmesg.

 Tratando de diagnosticar un problema de conectividad en la empresa, me encontré
con el hecho de que no podía determinar a ciencia el momento en que se producían los eventos que estaba visualizando a través de la salida del comando dmesg.

Este comando como primer campo de cada registro/linea muestra un timestamp con los segundos.nanosegundos que pasaron desde el booteo del equipo hasta el evento presentado, algo así


[349375.188024] eth0: no IPv6 routers present

[349375.220015] eth1: no IPv6 routers present


Como no me servía busqué en internet y encontré este post Con dos soluciones interesantes.

La primera, en Debian/Ubuntu se puede revisar un log igual pero con campos de fecha y hora.
cat /var/log/kern.log

La segunda y un poco más divertida es un script que parsea la salida de dmesg y la modifica para mostrarnos este dato. Cito la versión en Pearl:


#!/usr/bin/perl
 
use strict;
use warnings;
 
my @dmesg_new = ();
my $dmesg = "/bin/dmesg";
my @dmesg_old = `$dmesg`;
my $now = time();
my $uptime = `cat /proc/uptime | cut -d"." -f1`;
my $t_now = $now - $uptime;
 
sub format_time {
 my @time = localtime $_[0];
 $time[4]+=1;    # Adjust Month
 $time[5]+=1900;    # Adjust Year
 return sprintf '%4i-%02i-%02i %02i:%02i:%02i', @time[reverse 0..5];
}
 
foreach my $line ( @dmesg_old )
{
 chomp( $line );
 if( $line =~ m/\[\s*(\d+)\.(\d+)\](.*)/i )
 {
 # now - uptime + sekunden
 my $t_time = format_time( $t_now + $1 );
 push( @dmesg_new , "[$t_time] $3" );
 }
}
 
print join( "\n", @dmesg_new );
print "\n";


Copiamos esas lineas a un archivo de texto, guardamos, lo volvemos ejecutable con

chmod +x dmesg_for_humans

y listo, situados en el directorio donde lo guardamos ejecutamos ./dmesg_for_humans y tenemos una salida como esta:

[2012-02-23 11:54:50]  eth0: no IPv6 routers present



[2012-02-23 11:54:50]  eth1: no IPv6 routers present



Recomiendo leer el post que cito ya tiene una versión en python del script y los comentarios suman también.
Espero les sirva