Sto lavorando su uno script di shell che apporta alcune modifiche su un file txt solo se esiste, tuttavia questo ciclo di test non funziona, mi chiedo perché? Grazie!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Sto lavorando su uno script di shell che apporta alcune modifiche su un file txt solo se esiste, tuttavia questo ciclo di test non funziona, mi chiedo perché? Grazie!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Risposte:
Quando dici "non funziona", come fai a sapere che non funziona?
Potresti provare a capire se il file esiste effettivamente aggiungendo:
while [ ! -f /tmp/list.txt ]
do
sleep 2 # or less like 0.2
done
ls -l /tmp/list.txt
Potresti anche assicurarti di utilizzare una shell Bash (o relativa) digitando "echo $ SHELL". Penso che CSH e TCSH utilizzino una semantica leggermente diversa per questo ciclo.
while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
Se sei su Linux e hai installato inotify-tools, puoi farlo:
file=/tmp/list.txt
while [ ! -f "$file" ]
do
inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"
done
Ciò riduce il ritardo introdotto dallo stato di sospensione durante il polling ogni "x" secondi. Puoi aggiungere più eventi se prevedi che siano necessari.
--excludefiltrare i nomi dei file, ma non --includeignorare tutto tranne il nome del file. Il comando precedente dovrebbe utilizzare l' -qqargomento invece di >&/dev/nullsebbene.
--timeoutfrequenza del controllo, no? Il punto di inotifywait è che non ci sono sondaggi
inotifywaitpotrebbe bloccarsi indefinitamente se un file viene creato appena prima che inizi ad ascoltare gli eventi.
Mi sono imbattuto in un problema simile e mi ha portato qui, quindi volevo lasciare la mia soluzione a chiunque provasse la stessa cosa.
Ho scoperto che se avessi eseguito cat /tmp/list.txtil file sarebbe stato vuoto, anche se ero certo che ci fossero contenuti che venivano inseriti immediatamente nel file. Risulta che se metto un sleep 1;appena prima cat /tmp/list.txtche ha funzionato come previsto. Deve esserci stato un ritardo tra il momento in cui il file è stato creato e il momento in cui è stato scritto, o qualcosa del genere.
Il mio codice finale:
while [ ! -f /tmp/list.txt ];
do
sleep 1;
done;
sleep 1;
cat /tmp/list.txt;
Spero che questo aiuti a risparmiare a qualcuno una frustrante mezz'ora!
Come @ zane-hooper, ho avuto un problema simile su NFS. Su filesystem paralleli / distribuiti il ritardo tra la creazione di un file su una macchina e il "vederlo" sull'altra macchina può essere molto grande, quindi potrei aspettare fino a un intero minuto dopo la creazione del file prima che il ciclo while termini (e c'è anche un effetto collaterale di "vedere" un file già cancellato).
Questo crea l'illusione che la sceneggiatura "non funzioni" , mentre in realtà è il filesystem a far cadere la palla.
Mi ci è voluto un po 'per capirlo, spero che faccia risparmiare tempo a qualcuno.
PS Questo causa anche un numero fastidioso di errori "Stale file handler".
funziona con bash e sh entrambi:
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.."
Ecco una versione con un timeout in modo che dopo un certo periodo di tempo il ciclo termini con un errore:
# 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
Fai cosi
while true
do
[ -f /tmp/list.txt ] && break
sleep 2
done
ls -l /tmp/list.txt