Estoy trabajando en un script de shell que hace ciertos cambios en un archivo txt solo si existe, sin embargo, este ciclo de prueba no funciona, me pregunto por qué. ¡Gracias!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Estoy trabajando en un script de shell que hace ciertos cambios en un archivo txt solo si existe, sin embargo, este ciclo de prueba no funciona, me pregunto por qué. ¡Gracias!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Respuestas:
Cuando dice "no funciona", ¿cómo sabe que no funciona?
Puede intentar averiguar si el archivo realmente existe agregando:
while [ ! -f /tmp/list.txt ]
do
sleep 2 # or less like 0.2
done
ls -l /tmp/list.txt
También puede asegurarse de que está usando un shell Bash (o relacionado) escribiendo 'echo $ SHELL'. Creo que CSH y TCSH usan una semántica ligeramente diferente para este bucle.
while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
Si está en linux y tiene inotify-tools instaladas, puede hacer esto:
file=/tmp/list.txt
while [ ! -f "$file" ]
do
inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"
done
Esto reduce el retraso introducido por la suspensión mientras sigue sondeando cada "x" segundos. Puede agregar más eventos si prevé que son necesarios.
--exclude
que filtrar los nombres de archivo, pero no --include
ignorar todo excepto el nombre del archivo. El comando anterior debería usar el -qq
argumento en lugar de >&/dev/null
aunque.
--timeout
frecuencia de verificación, ¿no? El punto de inotifywait es que no hay votación
inotifywait
podría bloquearse indefinidamente si se crea un archivo justo antes de que comience a escuchar eventos.
Me encontré con un problema similar y me llevó aquí, así que solo quería dejar mi solución para cualquiera que experimente lo mismo.
Descubrí que si ejecutaba, cat /tmp/list.txt
el archivo estaría vacío, aunque estaba seguro de que el contenido se colocaba inmediatamente en el archivo. Resulta que si pongo un sleep 1;
justo antes del cat /tmp/list.txt
, funcionó como se esperaba. Debe haber habido un retraso entre el momento en que se creó el archivo y el momento en que se escribió, o algo por el estilo.
Mi código final:
while [ ! -f /tmp/list.txt ];
do
sleep 1;
done;
sleep 1;
cat /tmp/list.txt;
¡Espero que esto ayude a alguien a ahorrar una media hora frustrante!
Como @ zane-hooper, tuve un problema similar en NFS. En sistemas de archivos paralelos / distribuidos, el retraso entre la creación de un archivo en una máquina y la otra máquina "viendo" puede ser muy grande, por lo que podría esperar hasta un minuto completo después de la creación del archivo antes de que salga el ciclo while (y también hay un efecto secundario de "ver" un archivo ya eliminado).
Esto crea la ilusión de que el script "no funciona" , mientras que en realidad es el sistema de archivos el que está dejando caer la pelota.
Me tomó un tiempo darme cuenta, espero que le ahorre a alguien algo de tiempo.
PD: Esto también causa una cantidad molesta de errores de "manejador de archivos obsoletos".
funciona con bash y sh ambos:
touch /tmp/testfile
sleep 10 && rm /tmp/testfile &
until ! [ -f /tmp/testfile ]
do
echo "testfile still exist..."
sleep 1
done
echo "now testfile is deleted.."
Aquí hay una versión con un tiempo de espera para que después de un período de tiempo el ciclo termine con un error:
# After 60 seconds the loop will exit
timeout=60
while [ ! -f /tmp/list.txt ];
do
# When the timeout is equal to zero, show an error and leave the loop.
if [ "$timeout" == 0 ]; then
echo "ERROR: Timeout while waiting for the file /tmp/list.txt."
exit 1
fi
sleep 1
# Decrease the timeout of one
((timeout--))
done
Hazlo asi
while true
do
[ -f /tmp/list.txt ] && break
sleep 2
done
ls -l /tmp/list.txt