Pracuję nad skryptem powłoki, który wprowadza pewne zmiany w pliku txt tylko wtedy, gdy istnieje, jednak ta pętla testowa nie działa, zastanawiam się, dlaczego? Dziękuję Ci!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Pracuję nad skryptem powłoki, który wprowadza pewne zmiany w pliku txt tylko wtedy, gdy istnieje, jednak ta pętla testowa nie działa, zastanawiam się, dlaczego? Dziękuję Ci!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Odpowiedzi:
Kiedy mówisz „nie działa”, skąd wiesz, że to nie działa?
Możesz spróbować dowiedzieć się, czy plik faktycznie istnieje, dodając:
while [ ! -f /tmp/list.txt ]
do
sleep 2 # or less like 0.2
done
ls -l /tmp/list.txt
Możesz także upewnić się, że używasz powłoki Bash (lub pokrewnej), wpisując „echo $ SHELL”. Myślę, że CSH i TCSH używają nieco innej semantyki dla tej pętli.
while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
Jeśli korzystasz z Linuksa i masz zainstalowane narzędzia inotify-tools, możesz to zrobić:
file=/tmp/list.txt
while [ ! -f "$file" ]
do
inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"
done
Zmniejsza to opóźnienie wprowadzane przez uśpienie, podczas gdy nadal odpytywanie co „x” sekund. Możesz dodać więcej wydarzeń, jeśli przewidujesz, że są potrzebne.
--exclude
odfiltrować nazwy plików, ale nie --include
ignorować wszystkiego oprócz nazwy pliku. Powyższe polecenie powinno -qq
zamiast tego używać argumentu >&/dev/null
.
--timeout
, a nie częstotliwość sprawdzania, nie? Celem inotifywait jest to, że nie ma głosowania
inotifywait
może zawiesić się na czas nieokreślony, jeśli plik zostanie utworzony tuż przed rozpoczęciem nasłuchiwania zdarzeń.
Natknąłem się na podobny problem i doprowadził mnie tutaj, więc chciałem zostawić moje rozwiązanie każdemu, kto doświadcza tego samego.
Zauważyłem, że jeśli uruchomię, cat /tmp/list.txt
plik będzie pusty, mimo że byłem pewien, że zawartość jest natychmiast umieszczana w pliku. Okazuje się, że jeśli wstawię sleep 1;
tuż przed cat /tmp/list.txt
, zadziałało zgodnie z oczekiwaniami. Musiało być opóźnienie między utworzeniem pliku a jego zapisaniem lub czymś podobnym.
Mój ostateczny kod:
while [ ! -f /tmp/list.txt ];
do
sleep 1;
done;
sleep 1;
cat /tmp/list.txt;
Mam nadzieję, że pomoże to komuś zaoszczędzić frustrujące pół godziny!
Podobnie jak @ zane-hooper, miałem podobny problem na NFS. Na równoległych / rozproszonych systemach plików opóźnienie między utworzeniem pliku na jednej maszynie a „zobaczeniem” go na drugiej maszynie może być bardzo duże, więc mogłem odczekać do pełnej minuty po utworzeniu pliku, zanim pętla while zakończy działanie (i istnieje również skutek „zobaczenia” już usuniętego pliku).
To stwarza iluzję, że scenariusz „nie działa” , podczas gdy w rzeczywistości jest to system plików, który jest upuszczenie kuli.
Zajęło mi to trochę czasu, mam nadzieję, że to komuś zaoszczędzi trochę czasu.
PS Powoduje to również irytującą liczbę błędów „Stale obsługi plików”.
działa z bash i sh zarówno:
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.."
Oto wersja z limitem czasu, więc po pewnym czasie pętla kończy się błędem:
# 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
zrób to w ten sposób
while true
do
[ -f /tmp/list.txt ] && break
sleep 2
done
ls -l /tmp/list.txt