martes, 25 de enero de 2011

Tip: Como remover los molestos ^M

En ocasiones ya sea porque hemos editado un archivo en windows o porque algún colega nos ha pasado ún código al tratar de ejecutarlo nos regresa el siguiente error:
Es más al revisar el archivo con vi nos encontramos con algo como esto:

Como podemos ver cada línea tiene un caracter ^M al final, lo que hace que el shell no pueda determinar correctamente el final de cada linea. Esto es debido a que Unix usa como separador de linea LF(\n) mientras que Windows/DOS usa CR/LF(\r\n). Por tanto basta con eliminar los caracteres extras de nuestro archivo,  aunque hay una herramienta de nombre dos2unix, esta no esta presente de forma estándar. Por lo que nos abocaremos a hacer una subrutina que cumpla esta misma función.
La parte funcional la implementaremos usando el programa tr de la siguiente forma:
tr -d '\r' < archivo_a_limpiar > archivo_limpio
Ahora bien una función en el interprete de comandos se puede implementar de la siguiente forma:
Nombre_Funcion()
{
     Comando_1
      Comando_2
       ...
      Comando_N

}

Llamaremos a nuestra funcion strip_cr, para que la misma pueda procesar un archivo sobre demanda, debemos especificarlo mediante un parametro. Los parámetros en una función shell se especifican como $1,$2,... $9 para el primero, el segundo y hasta el noveno parametro.
Por tanto la entrada de nuestro comando tr sería de la siguiente forma:
tr -d '\r' < $1
La salida del comando no puede ser el mismo archivo de entrada, por lo que ocupamos la variable especial $$ que almacena nuestro id de proceso. Así:
tr -d '\r' < $1 > $1.$$
Sin embargo tendríamos que consultar siempre cual es el archivo mas reciente, que se llame igual que el original mas un "." (mucho lío ¿no les parece?). En lugar de eso después de obtener la salida sustituimos el original con el nuevo archivo:
tr -d '\r' < $1 > $1.$$
mv $1.$$ $1
Al final nuestra subrutina quedaría así:
strip_cr()
{
  tr -d '\r' < $1 > $1.$$
  mv $1.$$ $1
}

y al ejecutarla el resultado seria el siguiente:

Que como podemos ver carece ya de los caracteres ^M que se visualizaban antes.

viernes, 21 de enero de 2011

Anatomia general de un script unix

Un script unix puede ser definido como un archivo de texto que cumple las siguientes condiciones:
a) Esta escrito en un lenguaje entendible por un "interprete de comandos" (shell) (ksh,csh,awk,perl, solo por poner algunos ejemplos)
b) Cada uno de sus registros/lineas esta terminado por un caracter de nueva linea (LF)
c) Tiene permisos de ejecución

Como mencioné en el primer punto el contenido de nuestro archivo es entendible o interpretable en tiempo real, por un programa que verifica la sintaxis de cada unos de los comandos introducidos, este es por omisión el que estemos usando en ese momento.
Para saber cual es nuestro shell actual, podemos usar el siguiente comando.
#echo $SHELL
Sin embargo, los shell (solo para hablar de aquellos del SO) no son completamente compatibles en su sintaxis. Existen dos formas de "forzar" la ejecución de nuestros scripts en un shell en particular.
a) Ejecutando el script en una sesión aparte de ese shell en particular. Ejemplo:
# /usr/bin/ksh myscript.sh
b) Especificandolo en la primera linea de nuestro script, que en lo personal me parece la mejor practica. Esto se hace iniciando el archivo con una línea que cumpla con la siguiente sintaxis:
#!interprete_de_comandos_en_el_archivo argumentos_de_linea_interprete_de_comandos
No necesariamente se limita a interpretes de comandos de SO, sino que se extiende a otros lenguaje como perl, awk, php, python, etc. Algunos ejemplos:
#!/usr/bin/ksh
#!/usr/bin/awk -F:
#!/usr/bin/perl
En el segundo ejemplo, usé un parametro de linea para el programa awk (en este caso uno que indica que el separador de campos será el caracter ":", es decir el incluir esa linea y asumiendo que nuestro script se llame miawk.awk, sería el equivalente a escribir el siguiente comando
#/usr/bin/awk -F: miawk.awk

En cuanto a la separación de cada línea por un LF, es el separador de línea por omisión en todos los clones unix, sin embargo cuando editamos algo en windows y luego lo pasamos a unix, puede ser que tengamos una serie de caracteres ^M. Esta situación la abordaremos en un artículo posterior.

Los permisos de ejecución se otorgan a un archivo mediante el comando chmod. Este comando nos permite otorgar(usando el simbolo +) o revocar(usando el simbolo -), permisos de lectura(r), escritura(w) y ejecucion(x). Por tanto si queremos otorgar permisos de ejecucion a un script de nombre primero.sh basta que introduzcamos el comando:
#chmod +x primero.sh
En este comando hemos omitido a quien se le otorgan los permisos por lo que se le otorgan a todas las categorías: usuario(u), grupo(g) y otros(o). Si por seguridad quisieramos que solo nuestro usuario pueda ejecutar este script, tendriamos que agregar una u:
#chmod +ux primero.sh
Despues solo quedaria la ejecución de nuestro script. Si por casualidad hemos incluido la ruta actual (.) en el path de nuestro usuario bastara con:
#primero.sh
Sin embargo, sobre todo para el usuario de root se considera una mala practica y un riesgo de seguridad, por lo que tenemos que cambiar la referencia a nuestro script:
#./primero.sh

miércoles, 5 de enero de 2011

Bienvenidos a sobreviviendo IT

Este nuevo blog al contrario de Ichi's killing corner, estará dedicado a compartir lo poco o mucho que vaya aprendiendo día con día.
Y quien sabe... a estas alturas dos meses despues no me acuerdo que programe Jajaja.
Así que tambien ira siendo mi tumbaburros.
Espero que a los visitantes les llegue a gustar.