Introducción
Bienvenido a la tercera parte de la «Guía para principiantes de BASH». Si te has perdido los dos s anteriores, probablemente querrás saber qué hace que esta guía sea diferente a otras guías de scripting de BASH.
Esta guía está siendo escrita por un completo novato de BASH y para que como lector aprendas mientras yo aprendo. Aunque soy un principiante en BASH, vengo de un entorno de desarrollo de software, aunque la mayoría de las cosas que he escrito han sido para la plataforma Windows.
Usted puede ver los dos primeros guías visitando:
- Guía para principiantes de BASH – Hello World
- Guía para principiantes de BASH – Parámetros de entrada
Si eres nuevo en BASH scripting te recomiendo que leas las dos primeras guías antes de continuar con esta.
En esta guía destacaré cómo usar las sentencias condicionales para probar la entrada del usuario y para controlar cómo funciona un script.
Instalar rsstail
Para seguir esta guía necesitará instalar una aplicación de línea de comandos llamada rsstail que se utiliza para leer los canales RSS.
Si está usando una distribución basada en Debian/Ubuntu/Mint, escriba lo siguiente:
sudo apt-get install rsstail
Para Fedora/CentOS etc. escriba lo siguiente:
yum install rsstail
Para openSUSE escriba lo siguiente:
zypper install rsstail
La declaración IF
Abra un terminal y cree un archivo llamado rssget.sh escribiendo lo siguiente:
sudo nano rssget.sh
Dentro del editor nano introduzca el siguiente texto:
#!/bin/bash
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
Guarde el archivo pulsando CTRL y O y luego salga pulsando CTRL y X.
Ejecute el script escribiendo lo siguiente:
sh rssget.sh
El script devolverá una lista de títulos del feed RSS de linux.about.com.
No es un script demasiado útil porque sólo recupera los títulos de un feed RSS pero ahorra tener que recordar la ruta al feed RSS de Linux.about.com.
Abra el script rssget.sh en nano de nuevo y edite el archivo para que se vea como sigue:
#!/bin/bash
si [ $1 = «verboso» ]
entonces
rsstail -d -l -u http://z.about.com/6/o/m/linux_p2.xml;
fi
Ejecute el script de nuevo escribiendo lo siguiente:
sh rssget.sh verboso
Esta vez la fuente RSS vuelve con el título, el enlace y la descripción.
Analicemos el guión con un poco de detalle:
El #!/bin/bash aparece en cada script que escribimos. La siguiente línea se centra básicamente en el primer parámetro de entrada proporcionado por el usuario y lo compara con la palabra «verboso». Si el parámetro de entrada y la palabra «verboso» coinciden con las líneas entre entonces y fi se ejecutan.
El guión anterior es obviamente defectuoso. ¿Qué sucede si no se proporciona ningún parámetro de entrada? La respuesta es que se obtiene un error del tipo «operador inesperado».
El otro gran defecto es que si no se proporciona la palabra «verboso», entonces no ocurre nada en absoluto. Idealmente, si no proporciona la palabra «verboso», el script devolverá una lista de títulos.
Usa nano de nuevo para editar el archivo rssget.sh y modifica el código de la siguiente manera:
#!/bin/bash
si [ $1 = «verboso» ]
entonces
rsstail -d -l -u http://z.about.com/6/o/m/linux_p2.xml;
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
Guarde el archivo y ejecútelo escribiendo lo siguiente:
sh rssget.sh verboso
Aparecerá una lista de títulos, descripciones y enlaces. Ahora ejecútalo de nuevo de la siguiente manera:
sh rssget.sh títulos
Esta vez sólo aparece una lista de títulos.
La parte extra del script está en la línea 4 e introduce la sentencia else. Básicamente el script ahora dice que si el primer parámetro es la palabra «verboso» obtenga la descripción, enlaces y títulos para el feed RSS, pero si el primer parámetro es otra cosa, simplemente obtenga una lista de títulos.
El guión ha mejorado ligeramente, pero sigue siendo defectuoso. Si no se introduce un parámetro, seguirá apareciendo un error. Incluso si usted proporciona un parámetro, el sólo hecho de decir que no quiere ser verboso no significa que sólo quiere títulos. Es posible que hayas escrito mal, por ejemplo, o que hayas escrito palomas, lo que por supuesto no tiene sentido.
Antes de que intentemos aclarar estos problemas, quiero mostrarles un comando más que va con la declaración IF.
Edite su script rssget.sh para que se vea como sigue:
#!/bin/bash
si [ $1 = «todos» ]
entonces
rsstail -d -l -u http://z.about.com/6/o/m/linux_p2.xml;
elif [ $1 = «descripción» ]
entonces
rsstail -d -u http://z.about.com/6/o/m/linux_p2.xml;
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
Decidí deshacerme de la palabra «verboso» y la sustituí por «todo». Esa no es la parte importante. El script anterior introduce elif que es una forma corta de decir ELSE IF.
Ahora el guión funciona de la siguiente manera. Si ejecuta sh rssget.sh all entonces obtiene descripciones, enlaces y títulos. Si en vez de eso sólo ejecuta sh rssget.sh description sólo obtendrá títulos y descripciones. Si usted proporciona cualquier otra palabra, obtendrá una lista de títulos.
Esto introduce una forma de crear rápidamente una lista de frases condicionales. Una forma alternativa de hacer ELIF es usar lo que se conoce como sentencias IF anidadas.
El siguiente es un ejemplo que muestra cómo funcionan las sentencias IF anidadas:
#!/bin/bash
si [ $2 = «aboutdotcom» ]
entonces
si [ $1 = «todos» ]
entonces
rsstail -d -l -u http://z.about.com/6/o/m/linux_p2.xml;
elif [ $1 = «descripción» ]
entonces
rsstail -d -u http://z.about.com/6/o/m/linux_p2.xml;
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
más
si [ $1 = «todos» ]
entonces
rsstail -d -l -u http://lxer.com/module/newswire/headlines.rss
elif [ $1 = «descripción» ]
entonces
rsstail -d -u http://lxer.com/module/newswire/headlines.rss
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
fi
Siéntase libre de escribir todo eso si lo desea o copiarlo y pegarlo en su archivo rssget.sh.
El guión anterior introduce un segundo parámetro que le permite elegir entre «about.com» o «lxer.com» y un feed RSS.
Para ejecutarlo, escriba lo siguiente:
sh rssget.sh todo sobredotcom
o
sh rssget.sh all lxer
Por supuesto, puede reemplazar todo con descripciones o títulos para proporcionar sólo descripciones o sólo títulos.
Básicamente el código de arriba dice que si el segundo parámetro es aboutdotcom, entonces mire a la segunda sentencia, que es la misma que la del script anterior, o si el segundo parámetro es lxer, mire al interior de la sentencia para decidir si mostrar títulos, descripciones o todo.
Ese script se proporciona puramente como un ejemplo de una sentencia IF anidada y hay tantas cosas incorrectas con ese script que se necesitaría otro para explicarlas todas. El problema principal es que no es escalable.
Imagínate que quisieras añadir otro canal RSS como Everyday Linux User o Linux Today? El script se volvería enorme y si decidieras que quieres que la declaración interna de IF cambie, tendrías que cambiarla en múltiples lugares.
Mientras que hay un tiempo y un lugar para un SI anidado, deben ser usados con moderación. Normalmente hay una manera de refactorizar tu código para que no necesites el SI anidado en absoluto. Volveré sobre este tema en un futuro…
Veamos ahora cómo arreglar el problema de la gente que entra en los parámetros de duff. Por ejemplo, en el script anterior, si el usuario introduce algo distinto a «aboutdotcom» como segundo parámetro, aparece una lista de s del flujo RSS de LXER, independientemente de si el usuario introduce lxer o no.
Además, si el usuario no introduce «all» o «description» como primer parámetro, el valor por defecto es una lista de títulos que pueden ser o no los que el usuario desea.
Mire el siguiente script (o cópielo y péguelo en su archivo rssget.sh.
#!/bin/bash
si [ $2 = «aboutdotcom» ] ||| [ $2 = «lxer» ]
entonces
si [ $1 = «todo» | || [ $1 = «descripción» | | [ $1 = «título»
entonces
si [ $2 = «aboutdotcom» ]
entonces
si [ $1 = «todos» ]
entonces
rsstail -d -l -u http://z.about.com/6/o/m/linux_p2.xml;
elif [ $1 = «descripción» ]
entonces
rsstail -d -u http://z.about.com/6/o/m/linux_p2.xml;
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
más
si [ $1 = «todos» ]
entonces
rsstail -d -l -u http://lxer.com/module/newswire/headlines.rss
elif [ $1 = «descripción» ]
entonces
rsstail -d -u http://lxer.com/module/newswire/headlines.rss
más
rsstail -u http://z.about.com/6/o/m/linux_p2.xml;
fi
fi
fi
fi
Lo primero que hay que tener en cuenta es que el script se está haciendo bastante grande y se puede ver rápidamente lo fuera de control