Bash: Cómo esperar hasta que un archivo exista
Introducción
Cuándo trabajas con scripts Bash, a menudo te encuentras con escenarios en los que necesitas esperar a que se cree o esté disponible un archivo/fichero. Esto puede ser mientras esperas a que se descargue un archivo, se genere por un proceso diferente, o cualquier otra situación en la que quieras asegurarte de que un archivo existe antes de continuar.
En este artículo, exploraremos cómo lograr esta tarea de forma eficiente en Bash.
El script Bash de ejemplo
Comencemos con un script Bash sencillo que demuestra el concepto básico. El script esperará continuamente hasta que exista un archivo especificado y luego imprimirá un mensaje en la consola:
until [ -e /tmp/file.txt ]; do
sleep 1
done
echo File exists
Comenzamos usando la construcción de bucle until
para verificar una condición.
La condición del bucle ([ -e /tmp/file.txt ]
) se ejecutará mientras devuelva un estado de salida distinto de cero.
El cuerpo del bucle (sleep 1
) también se ejecutará mientras los comandos de prueba devuelvan un estado de salida distinto de cero.
El bucle finaliza una vez que el comando sale con un estado de salida cero.
Para los comandos de prueba de condición, estamos usando la
expresión condicional -e
de Bash
para verificar si el archivo existe (puede ser un archivo o un directorio).
También podríamos aprovechar las siguientes expresiones condicionales:
-f
para verificar si el archivo existe y es un archivo regular.-d
para verificar si el archivo existe y es un directorio.-s
para verificar si el archivo existe y no está vacío.
Una vez que salimos del bucle, imprimimos un mensaje en la consola: File exists
.
Este script es extremadamente útil tal y como está. No obstante, por múltiples motivos, el archivo podría no crearse nunca haciendo que el script espere para siempre.
Veamos cómo mejorar el script para evitar esta situación.
Cómo esperar a que se cree un archivo con timeout
El siguiente script contiene la misma lógica que el anterior con la adición de un timeout.
t=0
until [ -e /tmp/file.txt ] || (( t++ >= 5 )); do
sleep 1
done
[ -e /tmp/file.txt ] && echo File exists || echo Timeout
El script comienza definiendo una variable t
que se utilizará para contar el número de iteraciones.
La variable se inicializa a 0
.
Modificamos el bucle until
para incluir una condición adicional.
Ahora, el bucle se ejecutará mientras el archivo no exista y el número de iteraciones sea menor que 5
.
Una vez que el archivo existe o el número de iteraciones es mayor o igual que 5
, el bucle terminará.
La consola imprimirá un mensaje dependiendo de la existencia del archivo o del timeout.
Con esta modificación, el script se vuelve más robusto, asegurando que no esperará indefinidamente a un archivo que podría no crearse nunca.
En resumen, esperar a que un archivo exista en Bash es una tarea común, y entender cómo agregar un timeout puede hacer que tus scripts sean más resistentes en escenarios del mundo real.
¡Feliz scripting!