viernes, 6 de mayo de 2011

Colocar un script "propio" entre las llamadas de unos programas mediante tuberias



Supongamos:
$ls | grep s
Esto va a retornar todos los nombres de archivos que tengan "s", pero ahora supongamos:
$ls | ./miscript.sh | grep s
¿Qué debería contener el archivo miscript.sh para que eso siga funcionado como si no estuviera?
La respuesta: que miscript.sh sea capaz de leer la salida de ls y pasarla a grep.

¿Como?
Bien, tenemos que diseñar un script que su entrada "por parámetro" sea fijo. Vamos ver en caso de comando grep.


grep - sin pasar ninguna opción, funcionaría:
$grep PATRÓN FICHERO, habrá que pasar DOS PARÁMETROS para que funcione el comando.
$ls | grep PATRÓN, en este caso 1 parámetro y salida de ls será como de "FICHERO", porqué esperará la salida de tubería.

$grep, saldrá un mensaje ayuda.

Bien, grep funcionara en tres modos: sin pasar nada (generará el mensaje de ayuda), con 1 parámetro (cuando antes está una tubería y al parámetro tomará como PATRON) y con 2 parámetros (cuando buscamos un patrón en un FICHERO) y cuando mas de 2 busca en todos FICHEROs pasados por parámetro.

Probamos esto:
$ls | grep - (numero de parametro 0) - NO FUNCIONA

$ls | grep s miscript.sh - (numero de parametro 2) busca PATRON en FICHERO, como si no estuviera "ls |"
$grep miscript.sh - (numero de parametro 1) NO FUNCIONA

Conclusión: Nuestro script debe tener una regla especial para determinar en que momento ejecutar una orden adecuada.

Volvemos a nuestra pregunta:
 $ls | ./miscript.sh | grep s
¿Como hacer que funcione esto?

Diseñamos miscript.sh de siguiente manera: Si a miscript.sh le pasamos un parámetro que sea el nombre fichero, imprime linea-por-linea su contenido. Si le pasamos mas de 1, generará mensaje de error. Y si no le pasamos nada, entonces la entrada será de una tubería.

if [ $# -gt 1 ]; then
     echo "Pasar solo un parametro"!
elif [ $# -eq 1 ]; then
     while read line; do echo -e "$line"; done < $1
else
     while read A; do
              echo $A
     done
fi


Si rompemos las reglas, nuestro script no funcionará bien. (Como en grep que hemos visto).
 
De este modo, funcionara bien:
$ls | ./miscript.sh | grep s   =  $ls | grep s
 
[Puede descargar el script aqui.]

No hay comentarios:

Publicar un comentario