RSS

Manual de Unix

Documentando un shell me pidieron que la “ayuda” se desplegará como con el comando man, no igual porque seguro era muy difícil, sin embargo al menos formatear un documento de texto con secciones similares a las que muestra el comando.

Como siempre corrí a AWK, sin embargo ya encarrerado me detuve a pensar porque no verificaba como hacerlo bien.

http://upload.wikimedia.org/wikipedia/commons/d/db/Unix_manual.png

Descubrí que man tiene la opción -a la cual hará que me muestre todo lo que encuentre del comando, al introducir

man -a man

Me informó de la sección 7(miscelánea), en ella me habla de como formatear un archivo para man, es muy sencillo al menos para lo básico. El resultado por el momento es el siguiente:

 
Deja un comentario

Publicado por en febrero 24, 2014 en Uncategorized

 

Curso de AWK 1a. parte – Introducción

Con esta entrada daré inicio a un mini cursillo dell lenguaje AWK. La pregunta inicial podría ser porque AWK.

La primera vez que escuché que AWK era un lenguaje de procesamiento de patrones mi mente voló demasiado, hoy en día entiendo mejor esta descripción y recordando mi confusión inicial es que escribo esta entrada.

Pero porque aprender AWK?

La primera razón que se me ocurre es el hecho de que es un lenguaje muy pequeño, lo cual permite dominarlo en un tiempo relativamente corto, con un poco de práctica creo que es factible en una semana (si ya se tienen bases de programación) estar haciendo scripts sencillos de manera fluída y con algo más de dedicación en un par de meses puede uno encontrarse por encima del promedio de desarrollo.

El otro motivo de peso que me empuja es que es un lenguaje realmente poderoso para hacer ciertas tareas de manera sencilla y aún así muchas personas no pueden explotarlo de manera correcta.

Mi idea es brindar estas entradas de la manera en que yo fuí aprendiendo el lenguaje, es decir, primero aprenderlo mal y poco a poco aprenderlo bien, por lo que pido una disculpa si alguien ve que cometo algunos errores, solo considere que en su momento así entendí las cosas y eventualmente mejoré varios aspectos de mi desarrollo.

Historia
AWK fue originalmente desarrollado por Aho, Weinberger y Kernigan, posteriormente al ver las capacidades del lenguaje se crearon las versiones NAWK y GAWK las cuales agregaron nuevas características al lenguaje. Al final sirvió como base para la creación de Perl. actualmente podemos encontrar versiones para las principales plataformas y el proyecto GNU mantiene una versión que puede correr en Windows.

Instalación
Si te encuentras en un ambiente Unix es muy probable que ya cuentes con AWK instalado, recomendaría solo validar si se encuentra instalado GAWK, para ello ejecuta en una terminal:


gawk --version

En caso de que no se muestre la versión de GAWK intenta instalarlo con el gestor de paquetes de tu distribución.

Si te encuentras en Windows puedes decargarte GAWK desde la página del proyecto GNU. Otra opción es instalar Cygwin lo cual veo un poco engorroso si solo se quiere utilizar GAWK. La tercera opción es descargar MobaXTerm una aplicación que encapsula Cygwin en un solo ejecutable y que permite traerlo en una memoria usb y utilizarlo donde sea, lo puedes encontrar aquí.

Primeros pasos
La idea de los scripts de AWK es simple, tomar una entrada, típicamente un archivo, y leer de ella los registros (por defecto se delimitan por retorno de línea), por cada registro leído se ejecutara un conjunto de acciones(el cuerpo del script). Tiene un par de secciones especiales que nos permiten ejecutar instrucciones antes de procesar cualquier cosa y/o al final de procesar todo, si se está identificado con la POO yo lo asimilo con un constructor y un destructor.

Estructura
Aunque no sea correcto lo que a continuación diré, si facilitará el entendimiento inicial del lenguaje.
Para introducirnos en el manejo de scripts de AWK es importante entender como debemos estructurar un script:

BEGIN{
#Inicializacion
}
{
#Procesamiento principal
}
END{
#Procesamiento al finalizar
}

Lo primero que vemos en el script es la palabra BEGIN seguida de un bloque (en AWK los bloques de código se delimitan por medio de llaves), esto sirve para indicar que el bloque es el que se debe de ejecutar inmediatamente que se inicie la ejecución del script, incluso antes de leer el primer registro a procesar.
Despues del bloque BEGIN vemos que viene otro bloque que no esta precedido por ninguna palabra esto indica (por el momento) que es el bloque a ejecutar para cada registro que se lea y procese.
Por último vemos la palabra END seguida de un bloque, lo cual indica que el codigo que se encuentra dentro es el que se ejecuta una vez que se han procesado todos los registros de entrada.

Un script básico puede ser:


BEGIN{
print "Inicio del ejemplo"
}
{
print $0
}
END{
print "Fin del ejemplo"
}

Guardemos el script en el archivo ejemplo01.awk y creemos el archivo entrada.txt con el siguiente contenido:

aaa
bbb
ccc

Ahora ejecutemos el script de la siguiente forma:

awk -f ejemplo01.awk entrada.txt

Un detalle a notar aquí es que estamos utilizando la variable $0, es una variable muy especial ya que contiene el registro completo tal como fue leído de la entrada. Si deseáramos acceder a los campos del registro podemos hacerlo con las variables $1, $2, …, $NF donde NF es una variable especial que contiene el número de campos existentes en el registro actual, esto se debe a que se tener una cantidad variable de campos entre cada registro (:o).

Con esto hemos aprendido prácticamente lo básico de AWK oO. Esto se debe a que cuenta con un conjunto de funciones muy básicas, para darte una idea te recomiendo que tengas a la mano el Cheat Sheet de Peteris Krumis disponible aquí, en el hace un excelente trabajo en recabar información de AWK, muestra las variables predefinidas, opciones de línea de comando y funciones disponibles en el lenguaje.

A continuación haremos solo un breve recorrido por las variables especiales de AWK y terminaremos con algunos ejemplos:

FS Especifica el caracter (en GAWK permite una expresión regular) delimitador de campos
OFS Especifica el caracter delimitador de campos al imprimir el registro completo
$0 El registro completo
$1, $2, … Los campos contenidos dentro del registro actual
NR Número de registro actual procesado por el script
FNR Número de registro actual del archivo en curso
FILENAME El nombre del archivo del cual se está leyendo actualmente la entrada

 
Deja un comentario

Publicado por en agosto 25, 2011 en Uncategorized

 

Programar es fácil

En muchas ocasiones al llegar a una entrevista de trabajo me reciben con un caluroso

“Sabe programar en …?”

Aún no entiendo porque no me preguntan

“Conoces la programación estructurada?”
“Has programado orientado a objetos?”

o mejor aún, ponerme un problema que deba de resolver con pseudocódigo. No entiendo que es un programador de Java, .Net, C, etc. etc. Porque la gente de recursos humanos nos entrevista con preguntas tan cerradas. Donde quedó toda la teoría?

Cuando salí de la carrera era bueno en Turbo Pascal y ensamblador… profesionalmente nunca los he programado. Me considero afortunado porque en cada empleo he aprendido un lenguaje nuevo o algo nuevo de un lenguaje que ya conocía.

Creo que programar es fácil, lo difícil en realidad es hacerse de un portafolios de ideas que nos permitan formular una solución factible para un problema real.

Hace poco me enteré de GILD, un sitio que hace pruebas para rankear a los programadores, me suscribí y en estos momentos estoy realizando la siguiente prueba. No me considero un “programador de Perl”, asi que vamos a intentar hacerlo con algo que desconocemos…

Primero que nada vemos que hay que leer un archivo, gogleemos “Perl leer un archivo linea a linea”, nos vamos aqui. Ya tenemos el esqueleto:


TEST = "test.txt";
open(TEST) or die("No se pudo abrir el archivo.");
foreach $line () {
chomp($line);
#Aqui vamos a procesar el archivo
}

Ahora me detengo a pensar como leo el parámetro de la línea de comando, Google “perl commandline args” aqui. Y ahora tenemos el siguiente código:

$num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUtilice:\n\t passwordrecovery.pl file\n";
exit;
}
$fileInput=$ARGV[0];
open(fileInput) or die("Could not open log file.");
foreach $line () {
chomp($line);
#Aqui vamos a procesar el archivo
}

Muy bien! ya podemos leer del archivo pasado por línea de comando. Leamos la primera línea que tiene el password, inmediatamente despues de abrir el archivo agregaremos:

$cryptedPwd=;
chomp($cryptedPwd);

Y ahora vamos por partir la linea en palabras, Google “perl split string”, que nos lleva aquí. Nuestro script de perl debe de procesar el archivo así:

foreach () {
chomp($_);
@words = split(/[^a-zA-Z]/);
}

Ahora recorramos el arreglo de tokens, Google “perl array foreach”, aquí, ojo que el foreach lo tomamos “prestado” de cuando leímos línea por línea el archivo.

foreach () {
chomp($_);
@words = split(/[^a-zA-Z]/);
foreach (@words) {
print $_ . "\n";
}
}

Este código nos imrpime las “palabras” en el archivo, o no? Ok esta imprimiendo cadenas vacías, como filtramos solo los elementos que tienen caracteres alfabeticos? Google “perl if regexp”, aquí. Finalmente tenemos el siguiente script:

$num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUtilice:\n\t passwordrecovery.pl file\n";
exit;
}

$fileInput=$ARGV[0];
open(fileInput) or die("Could not open log file.");

$cryptedPwd=;
chomp($cryptedPwd);

$maxLengthPwd=8;
$minLengthPwd=5;
@digits=[0, 2, 4, 8];

#Se quito $line para pasar a $_
foreach () {
chomp($_);

@words = split(/[^a-zA-Z]/);

foreach (@words) {
if ($_ =~ /[A-Za-z]/){
print $_ . "\n";
}
}
#print $_
}

Para los que como yo no conocen perl, hay que guardar el script en un archivo y ejecutarlo de la siguiente manera:
perl passwordrecovery.pl passrecovery-a.in
El archivo passrecovery-a.in lo obtuve de la pagina de GILD.

La idea de este post es recomendarles que no nos preocupemos tanto por ser una referencia andando de un lenguaje, más bien debemos prepararnos con temas teóricos de algoritmos, ejercitarnos con retos y mantenernos activos en la resolución de problemas (con esto quiero decir que si lo que haces ya no es un problema para tí, busca un nuevo problema). Como ingenieros tenemos la tarea de ser generadores de soluciones y no solo técnicos programadores. Debemos de ser personas preocupadas por ser parte de la solución y no solo implementarlas, ya que en los equipos de trabajo requerimos de resolver problemas no de traducir algoritmos.

P.D. Les dejo las siguientes páginas muy entretenidas para mantenerse “en forma” ya que como dije, programar es fácil.

hacker.org
projecteuler.net

 
Deja un comentario

Publicado por en julio 18, 2011 en Uncategorized

 

Recuperando el ViewState en JMeter

Recientemente me integré a un proyecto desarrollado en Java. Las tareas a las que fuí asignado era apoyo a un arquitecto en tareas de revisión de la arquitectura actual para validar que no tenía problemas en la implementación, por lo las tareas que iniciamos era la ejecución constante de cortos ciclos de negocio para probar el desempeño de la aplicación para lo cual utilizamos JMeter una herramienta para la ejecución de pruebas de desempeño.

En alguna ocasión anterior ya había intentado trabajar con esta herramienta pero mi experiencia no fue exitosa por el tema que hoy nos acontece: la recuperación del ViewState entre las invocaciones a la aplicación.

El ViewState no es otra cosa más que un mecanismo para mantener el estado de una página. La mayoría de las páginas que hay en internet actualmente apuntan a la solución de utilizar una expresión regular para recuperar este valor, por ejemplo esta página, la cual nos indica utilizar un post procesador del tipo Regular Expresion Extractor con la siguiente expresión:

<input\s+type="hidden"\s+name="javax.faces.ViewState"\s+id=
"javax.faces.ViewState"\s+value="([.+?]+)"

De entrada analicemos un poco esto y me confieso desconocedor de las expresiones regulares en Java, (este análisis que pongo a continuación lo hago basándome a que las expresiones que acostumbro a utilizar en el shell son las descritas aquí), la parte interesante aquí es
([.+?])
primero que nada vemos que los paréntesis nos permiten agrupar una subexpresión para posteriomente hacer referencia a ella, y en la subexpresión
<code[.+?]
los corchetes me permiten indicar un conjunto de posibles caracteres, pero dentro de el veo un punto “.” el cual representa cualquier caracter y que puede presentarse 1 ó más veces “+” y posteriormente la interrogación indicando 0 ó 1 ocurrencia, no la entendí, si alguien lo hace por favor explíqueme. En mi caso la cambié por la siguiente:
([^"]+)
lo cual indica cualquier caracter excepto la doble comilla. Hasta aquí todo parecía bien, sin embargo yo me he encontrado con un pequeño problema: ¿que pasa si el valor está codificado y debido a esto incluye caracteres como \r o \n? Ese fue mi problema ya que a pesar de que la expresión capturaba la cadena apropiada JMeter no la podía trabajar correctamente (eventualmente creo que el error al final fue que aún faltaba un HTTP Cookie Manager, lamentablemente por el momento no lo puedo comprobar).

Es por eso que opté por buscar algo más. Y lo encontré aquí. Resulta que existe otro PostProcesador, el XPath Extractor, este nos permite referenciar un elemento dentro un documento XML y con la expresión adecuada podemos recuperar el valor. La expresión en cuestión es la siguiente:

string(//input[@name='javax.faces.ViewState']/@value)

Y con esto tuve todo mi problema resuelto. Sin embargo me confieso de igual forma desconocedor de XPath por lo que accedí al siguiente recurso de la red para generarme un panorama.

Espero que les sea de utilidad.

 
Deja un comentario

Publicado por en julio 13, 2011 en Java, JMeter

 

Hola Mundo!

Bueno y después de mucho pensarlo por fin daré inicio a este proyecto…

La idea original era hacer una serie de posts acerca de programación en Unix, sin embargo no he tenido el tiempo suficiente para preparar todo lo que tenía pensado, pero espero eventualmente retomar algunas partes de aquellas ideas.

La razón por la cual inicie es sencilla: tuve un problema que me ha costado mucho resolver y que gracias a algunas respuestas en un foro he podido resolver. La parte desagradable ha sido el tiempo que me ha llevado llegar a la solución, por lo que quiero contribuir a que pronto puedan encontrar las respuestas a sus problemas de manera más sencilla.

Sin más preámbulo iniciemos.

 

“Es que por más que lo busco no lo busco” C.J.N.B.

 
Deja un comentario

Publicado por en junio 28, 2011 en Personal

 
 
Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.