En este apunte práctico mi objetivo es aprovechar la técnica Pomodoro en Linux, sin usar para eso software o aplicaciones externas.
Todo esto que sigue a continuación vamos a tener que realizarlo por medio de un código escrito en Bash.
Pero una buena pregunta antes de continuar es…
¿Qué es la técnica Pomodoro?
Bueno, se trata de una técnica que puede servirnos para utilizar mejor el tiempo que vamos a dedicarle a una tarea. El concepto fue credo por Francesco Cirillo.
Mi super resumen: el objetivo es dividir una tarea en intervalos fijos de tiempo, separando cada intervalo por una pequeña pausa de descanso.
Creo que se va a entender mejor revisando un caso:
Me concentro en una tarea, por ejemplo la de escribir este texto, por quince minutos con una dedicación completa.
Luego tomo un par de minutos de descanso. Y terminada la pausa vuelvo a trabajar por otros quince minutos. Acto seguido viene otro micro recreo.
Y repito este ciclo hasta completar mi objetivo, agregando en el medio algunos periodos de descanso más largos.
El código que sigue a continuación va a ayudarme a cronometrar esos intervalos, con la menor cantidad de distracciones posibles.
¿Qué necesita este programa para ser efectivo?
Bueno, como ya dije, lo que necesito es poder concentrarme en una tarea por pequeños intervalos de tiempo.
Si bien para poder estar enfocado necesito aplicar fuerza de voluntad, hay algo para lo que usar solamente fuerza de voluntad pocas veces alcanza. Y ese algo es la internet.
Para que este programa funcione, necesito desconectarme de la red por al menos quince minutos sin interrupciones. Y luego el programa tiene que volver a conectarme.
Y es importante que el programa sea difícil de “apagar” para no buscar hacer trampa reconectando la red.
Lo verdaderamente complicado es que en Linux no existe nada que que no pueda ser contrarrestado, si cuento con los permisos suficientes para realizar la acción.
Lo que quiero entonces es que se vuelva muy molesto interrumpir el programa antes de que el mismo termine.
Una primera versión del código
Con esta combinación de comandos puedo conseguir, al menos en principio, lo que estoy buscando:
nmcli networking off & sleep 900; nmcli networking on
Se trata de dos comandos que se activan en conjunto (por medio del conector “&”).
Por un lado tengo el comando:
nmcli networking off
Según su manual:
NAME
manual de nmcli
nmcli – command-line tool for controlling NetworkManager
Esto es, nmcli es una herramienta de la terminal que sirve para controlar el manager de conexiones.
Al apagar y prender nmcli con “on/off” desactivo todas las interfaces que manejan la conexión a la red. Y por supuesto desactivando el modem pierdo la tan deseada conexión a internet en la máquina.
Puede que esta no sea la mejor opción para desconectarme, pero cumple con lo que estoy buscando. No puedo navegar mientras esta opción se encuentra apagada.
Lo siguiente es el comando:
sleep 900
Sobre este comando, el manual me dice:
NAME
Manual de sleep
sleep – delay for a specified amount of time
Según entiendo lo que hace el comando sleep es dejar la terminal pausada (o en espera) para ejecutar el siguiente comando por la cantidad de tiempo que especificamos.
En este caso ese tiempo es 900 segundos o lo que es lo mismo, 15 minutos.
Es verdad que se le puede especificar el tiempo en minutos usando la opción “-m”… pero es más fácil de este modo.
Entonces con esa cadena de comandos: me desconecto de internet, la terminal espera quince minutos y luego vuelvo a re conectarme por medio de:
nmcli networking on
Bastante bien. Pero puedo mejorar este programa un poco más.
Versión 2.0: Ahora con más molestias
Un problema del código anterior es que puedo interrumpirlo muy fácilmente.
Si en cualquier momento lo cancelo y vuelvo a activar “nmcli”, voy a volverme a conectar a internet. Acto seguido voy a estar navegando redes sociales en lugar de completar mi objetivo y la técnica Pomodoro no va a servir de nada.
Para esta nueva versión lo que voy a tener que hacer es crear un nuevo documento. Este documento lo voy a llamar “pomodoro.sh” y va a ser la base para nuestra aplicación.
El código que voy a usar es el siguiente:
#!/bin/bash # Pomodoro rápido para la terminal # Este código deshabilita la interfaz de red por un intervalo de 15 minutos. # Reviso si el archivo de bloqueo existe o voy a crearlo. archivo_bloqueo="/tmp/deshabilitar_red.lock" if [ -f "$archivo_bloqueo" ]; then echo "El archivo de bloqueo ya existe." exit 1 else touch "$archivo_bloqueo" fi # Establezco permisos más restrictivos en el archivo de bloqueo. chmod 400 "$archivo_bloqueo" # Deshabilito la interfaz de red. nmcli networking off # Muestro una cuenta regresiva de 15 minutos en la terminal. for i in {900..1}; do printf "\rLa interfaz de red se volverá a habilitar en %d segundos..." "$i" sleep 1 done # Vuelvo a habilitar la interfaz de red. nmcli networking on if [ -f "$archivo_bloqueo" ]; then # modifica el nombre del archivo creado al principio para borrarlo. chmod 600 "$archivo_bloqueo" else echo "El archivo de bloqueo no existe." fi # Elimino el archivo de bloqueo. rm "$archivo_bloqueo"
Ahora necesito cambiar los permisos para poder ejecutar el código:
chmod +rx pomodoro.sh
Y para ejecutar el programa escribo en la terminal:
./pomodoro.sh
Para usar el programa necesito estar en el directorio donde se encuentra el archivo.
Nuestro programa tiene dos características principales para revisar:
Cuando comienza el script, tengo el siguiente bloque de código:
# Reviso si el archivo de bloqueo existe o voy a crearlo. archivo_bloqueo="/tmp/networking_disabled.lock" if [ -f "$archivo_bloqueo" ]; then echo "El archivo de bloqueo ya existe." exit 1 else touch "$archivo_bloqueo" fi
Esto revisa si el archivo “deshabilitar_red.lock” existe en la carpeta “/tmp/”.
Si el archivo no existe lo crea y continua. Pero si el archivo existe, el programa termina.
La idea es que este archivo impide utilizar el programa varias veces seguidas. Mientras el archivo “deshabilitar_red.lock” exista no puedo tratar de volver a conectar la red usando de nuevo el mismo código.
Al mismo tiempo, transforma en una molestia el acto de cancelar el código mientras funciona, porque de hacerlo tendría que ir hasta el directorio “tmp” para buscar el archivo generado y borrarlo manualmente.
Y los permisos del archivo son modificados con:
chmod 400 "$archivo_bloqueo"
Por lo que para borrarlo necesito buscarlo y si o si utilizar el permiso sudo. Doblemente molesto.
Al terminar el código, otra función se va a encargar de borrar el documento para empezar desde cero cuando vuelva a invocar al programa.
2- Ahora el programa me dice que tengo 900 segundos para enfocarme en mi objetivo.
for i in {900..1}; do printf "\rLa interfaz de red se volverá a habilitar en %d segundos…" "$i" sleep 1 done
Con esto en la terminal me aparece un mensaje que me indica en cuantos segundos voy a volver a tener internet.
Este recordatorio hace que se me vuelva más fácil concentrarse, porque nos recuerda que es un intervalo corto y nos ayuda a mantenernos enfocados.
Y la función encargada en volver a reactivar la red es:
# Vuelvo a habilitar la interfaz de red. nmcli networking on if [ -f "$archivo_bloqueo" ]; then # modifica el nombre del archivo creado al principio para borrarlo. chmod 600 "$archivo_bloqueo" else echo "El archivo de bloqueo no existe." fi # Elimino el archivo de bloqueo. rm "$archivo_bloqueo"
Esto vuelve a establecer la red con el comando nmcli, y borra el archivo que habiamos creado para no volver a ejecutar el programa múltiples veces.
Problemas de la versión 2.0:
Creo que el verdadero problema que tiene el programa es que puede deshabilitarse por medio del comando:
nmcli networking on
Si utilizo ese comando desde otra terminal, vuelvo a “prender” internet.
Eso se podría resolver por ejemplo si cambiamos el nombre del comando “nmcli”, para que no pueda saber cómo invocarlo.
Antes de continuar, tengo que conocer donde se encuentra el directorio con el comando “nmcli”.
Eso lo hago con el comando “which” que enseña el camino al directorio:
which nmcli
/usr/bin/nmcli
Entonces si cambio el nombre del directorio por algo compilado, de esta forma:
sudo mv /usr/bin/nmcli /usr/bin/sfsfirjjjkxoyuojir5rehtg
Al hacer eso necesitaría escribir “sfsfirjjjkxoyuojir5rehtg” para invocar al comando “nmcli”, lo que convertir la actividad en algo ultra molesto.
Luego podría deshacer el cambio con:
sudo mv /usr/bin/sfsfirjjjkxoyuojir5rehtg /usr/bin/nmcli
¿Por qué esta solución no es una buena idea?
Aunque puede funcionar, también significa modificar un directorio importante del sistema.
Por eso aunque creo que puede funcionar, prefiero no hacerlo y confiar al menos en un grado en mi autocontrol para no reiniciar el contador y volver a activar internet.
O también podemos revisar otra versión del programa.
Versión 2.1: buscando más pomodoro
Esta es una nueva versión del código.
La principal diferencia con la versión anterior es que ahora casi todo se encuentra organizado en funciones, para que resulte más fácil de entender y mejorar en el futuro.
#!/bin/bash # Pomodoro 2.1 rápido para la terminal # Este código deshabilita la interfaz de red por un intervalo x de minutos. # modo de uso: pomodoro.sh argumento (número entero representando minutos) lockfile="/tmp/pomodoro_network.lock" # función para borrar el archivo de bloqueo function cleanup() { rm -f "${lockfile}" } # Reviso si el archivo de bloqueo existe o voy a crearlo. function create_and_check_lockfile() { if [ -e "${lockfile}" ]; then echo "El programa ya se encuentra en ejecución." exit 1 fi touch "${lockfile}" && chmod 600 "${lockfile}" || exit 1 } # Interrumpir la red por medio del comando nmcli function disable_network() { local retries=2 local sleep_time=5 for ((i=1; i<=retries; i++)); do nmcli networking off if [ $? -eq 0 ]; then # Mostrar notificación del comienzo del programa notify-send "Pomodoro comienza" "Internet fue interrumpida para que puedas dedicarte a tu tarea." echo "La interfaz de red fue interrumpida." return 0 else echo "Error: internet no pudo ser desconectada (intento núm: $i/$retries). Volver a intentar en $sleep_time segundos..." sleep $sleep_time fi done echo "Error: No se pudo desconectar internet luego de $retries intentos." return 1 } # conectar la red por medio del comando nmcli function reenable_network() { local retries=2 local sleep_time=5 for ((i=1; i<=retries; i++)); do nmcli networking on if [ $? -eq 0 ]; then # Mostrar notificación para avisar que ya hay internet notify-send "Pomodoro terminado" "Podés descanzar unos minutos antes de volver a tu tarea." echo "La interfaz de red fue habilitada." return 0 else echo "Error: internet no pudo ser establecida (intento núm: $i/$retries). Volver a intentar en $sleep_time segundos..." sleep $sleep_time fi done echo "Error: No se pudo conectar la red luego de $retries intentos." return 1 } # Revisar por argumentos de tiempo if [ $# -eq 0 ]; then WAIT_TIME=10 else WAIT_TIME=$1 if ! [[ "$WAIT_TIME" =~ ^[0-9]+$ ]]; then echo "Agregar número entero $0 <tiempo en minutos>" exit 1 fi fi # convertir el tiempo en segundos para sleep WAIT_TIME=$(( WAIT_TIME * 60 )) # Comienza el programa llamando las funciones create_and_check_lockfile if [ $? -ne 0 ]; then exit 1 fi echo "$(date +"%Y-%m-%d %H:%M:%S") - Deshabilitar conexión de red..." if ! disable_network; then echo "Error: no se pudo desconectar la red" cleanup exit 1 fi echo "$(date +"%Y-%m-%d %H:%M:%S") - Interfaz de red desconectada. La conección va a volver en $WAIT_TIME segundos..." sleep $WAIT_TIME if ! reenable_network; then echo "Error: No se pudo habilitar la red." cleanup exit 1 fi cleanup
Otra mejora es que el programa permite ahora que le pasemos la cantidad de minutos que queremos pasar con la técnica Pomodoro. Y si no le damos ningún argumento, el tiempo mínimo sin conexión es de 10 minutos.
# Revisar por argumentos de tiempo if [ $# -eq 0 ]; then WAIT_TIME=10 else WAIT_TIME=$1 if ! [[ "$WAIT_TIME" =~ ^[0-9]+$ ]]; then echo "Agregar número entero $0 <tiempo en minutos>" exit 1 fi fi # convertir el tiempo en segundos para sleep WAIT_TIME=$(( WAIT_TIME * 60 ))
Todavía tenemos algo similar a un problema: la red puede ser restablecida utilizando la interfaz gráfica o el comando nmcli desde otra terminal.
De todas maneras lo mejor es no pensar en eso, una vez que marcamos un lapso para dedicarnos en algo tenemos que resolver cumplir con ese lapso.
Lo más importante para que todo esto funcione: necesitamos establecer un objetivo razonable. Y necesitamos luego dedicarle a ese objetivo un tiempo sin distracciones para poder entender mejor lo que estamos haciendo.
Conclusión:
Este es mi primer intento para crear un programa Pomodoro en la terminal de Linux.
Tal vez puedas usar el código como base para crear algo mejor. Incluso probar agregarle mejoras con una inteligencia artificial permite construir algo complejo de una forma bastante rápida.
En lo que a mi respecta, aprendí mucho creando todo. Espero que te sirva de utilidad, y si te interesa decir algo sobre esto espero tus comentarios o mensajes por correo electrónico.
La seguimos en el siguiente apunte.