lunes, 25 de enero de 2021

Bash, scripts, bucles... y mi aMule

Descubro que mi aMule, desde hace un tiempo, tiene un comportamiento raro: cuando arranca, se conecta rápidamente a fuentes y se pone a descargar a mucha velocidad... pero al cabo de poco tiempo se congela la descarga y, aunque te sigue marcando, incluso, que mantiene una alta velocidad, y la indicación de que estás conectado... en realidad no descarga nada, o lo está haciendo a una velocidad ínfima, que no tiene nada que ver con la que marca. Y se puede pasar un rato largo así. No se si es que mi proveedor de internet intenta ‘caparla’, o qué. Y entonces se me ocurrió una idea...

Y la idea es que, si consiguiese crear una orden que, por ejemplo cada 3 minutos (dependerá del tiempo que vea que ‘se me congela’ determinada descarga), dijese a mi Debian que cierre el aMule, que espere unos segundos y que lo vuelva a arrancar… y repita esto contínuamente, me sería muy útil, para no estar pendiente de ir haciéndolo a mano si quiero descargarme un fichero grande (por ejemplo, una película de 2,5 GB) con rapidez. Y así me metí en el lío que voy a contar hoy.

Los primeros pasos
Buceando por Google (bueno, ahora uso DuckDuckGo) llegué a unos conceptos que me parece útil apuntarlos:
a) Que para lanzar determinada orden (comando) cada cierto tiempo, basta indicar, por consola…
watch -n número_segundos comando
b) Que para cerrar un proceso de usuario, puede usarse la orden 'pkill' (también, 'killall') con...
pkill nombre_proceso
(el nombre del proceso se puede ver, por ejemplo, con Menu-Administración-Monitor del sistema)
c) Que para forzar una pausa, basta escribir el mandato
sleep número_segundos


Jugando a ser programador
Y empecé a enredar con estas ideas. Por ejemplo, veo que la orden
watch -n 360 pkill amule
cerraba mi aMule cada 6 minutos. Pero nada mas, no lograba encadenar el arranque con un script… hasta que mis amigos del Foro de EspacioLinux me abrieron los ojos con el concepto del ‘Bucle en Bash’.
Me pasé varios días estudiando alternativas con el famoso condicional while (‘mientras’…) de sintaxis...
while [ condición ]; do
[mandato/s a ejecutar]
done

incluso me asomé al until (‘hasta que’...(no se presente una condición), do..., y al if-then (si… entonces haz…) y si no (else…) haz esto otro, con sintaxis
if [ condición ]; then
‘mandato B’
else
‘mandato C’
fi

Tonteé con diversas alternativas para crear algún script que trabajase en bucle, repitiendo apagados y encendidos, con las pistas que iba obteniendo, como el script
#!/bin/sh
while [ 0 -lt 1 ]; do
sleep 60 && pkill amule && sleep 10
amule
done

pero desgraciadamente solo funcionaba el primer ciclo de apagado y encendido.
Aprendí también, en el Foro mencionado, algunas cositas interesantes como ese [ 0 -lt 1 ] que creo que tiene que ver con ‘argumentos’ del interprete de comandos (-lt significa ‘menor que...’) y que sirve para saber si está funcionando el proceso... 
Pero claro, nunca estudié Programación, no conozco la mayoría de los comandos, apenas reconozco algún ‘operador’, lo de los ‘argumentos’ me suena a chino… así que (haciendo 'de la necesidad, virtud'), seguí buceando por Google, encontré (y entendí mejor) el comando ‘pidof nombre_proceso’ que generará el número de identificación (o PID) de ese proceso (y, por ello, si está activado), refresqué mis ideas sobre cómo trabajar con ‘variables’ en Bash, hice varios ‘proyectos de script’…
Pero aquello seguía sin funcionar.


El desenlace
Hasta que di un paso a atrás, dejé de empeñarme en la idea del super-script que funcione en bucle, etc, etc. y, olvidándome de la ortodoxia, y de las soluciones tradicionales, y decidí atenerme al alcance de mis conocimientos en programación, que realmente son mínimos, y a mi imaginación, a mi sentido común, a mi capacidad de análisis…
… Y se me abrieron las puertas del cielo cuando decidí pensar no en una única instancia (el super-script) sino en dos instancias (dos procesos) lanzados independientemente.
Entonces (me dije), por un lado tendré que hacer que el amule se ejecute repetidamente (¡Y eso lo hace la instrucción ‘watch’…!) y por otro que se apague cada cierto tiempo (¡Y eso lo daría un sencillo script con el condicional ‘while’ (mientras esté encendido… que se apague cada cierto tiempo)…!
En una palabra (los ajustes los obtuve tras varias pruebas) llegué a definir ésto:
Proceso 1: la orden (por consola)
watch -n 20 amule
arranca el amule cada 20 segundos. Y…
Proceso 2: el script (que llamaré amule0.sh)
#!/bin/bash
amule=`pidof amule`
while [ $amule -gt 0 ]; do
sleep 180
pkill amule
done

indica, simplemente, que ‘mientras (while) esté funcionando… espera 180 segundos, y ciérralo’, donde (en este script) la variable ‘$amule’ defino que sirva para aportar el número del PID del amule y ‘-gt’ es la convención que se usa, en Bash para decir ‘mayor que…’ (y, por tanto, si el PID es mayor que 0, es que el proceso está funcionando)
Y, arrancando ambos procesos (independientemente, cada uno en su consola) la cosa funciona. Naturalmente, en vez de 180 puedo poner 300, o 420 segundos, etc... para alargar su 'tiempo continuado de funcionamiento'.

Remate final
Y ahora, con la moral por las nubes, para hacerlo más bonito, me creo un par de lanzadores en el escritorio (eso si marcando en ambos eso de ‘launch in terminal’), indicando en ‘command’ (respectivamente)
watch -n 20 amule
y
sh amule0.sh

para que, con dos simples clics, en su orden, se ponga a funcionar el amule y, cada unos 160 segundos, se apague, y vuelva a arrancar.


NOTA COMPLEMENTARIA:
Como norma general, descubri (cronometrando, la deducción es más ‘enrevesada’), que aplicando estas cosas, el amule está apagado el tiempo que indiques en ‘watch’ y encendido el tiempo que resta hasta el indicado en ‘sleep’ (en el ejemplo, en cada ciclo amule está parado durante 20 segundos y arranca y descarga durante 160... o lo que haya previsto).

Pero confieso que me queda un reto pendiente: aprender algo más sobre la programación en Bash. Hasta el punto de que, ‘en el fragor de la batalla’ (de mis búsquedas por Google) empecé a resumir las ideas básicas montándome un ‘Bash para torpes’, que a lo mejor algún día publico aquí. 

Claro que, en realidad, no se a donde puede conducir (salvo a tener una cierta 'culturilla'), porque siempre me quedará lo de conocer en profundidad el montón de comandos, y operadores lógicos, relacionales, de redireccionado, etc, etc que existen. Y es que me temo que lo que yo pretendo, jugar al ‘scripting’ por alguna eventual ocurrencia es... como largarte a Suecia a pasar un fin de semana, sin saber nada de sueco. O como querer tocar el piano sin saber solfeo. Vamos, que se necesitará 'tener un poco de buen oido’ para que lo que suene... suene 'algo bien'.

No hay comentarios:

Publicar un comentario