Я работаю над сценарием оболочки, который вносит определенные изменения в текстовый файл, только если он существует, однако этот тестовый цикл не работает, интересно, почему? Спасибо!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Я работаю над сценарием оболочки, который вносит определенные изменения в текстовый файл, только если он существует, однако этот тестовый цикл не работает, интересно, почему? Спасибо!
while [ ! -f /tmp/list.txt ] ;
do
sleep 2
done
Ответы:
Когда вы говорите «не работает», откуда вы знаете, что это не работает?
Вы можете попытаться выяснить, существует ли файл на самом деле, добавив:
while [ ! -f /tmp/list.txt ]
do
sleep 2 # or less like 0.2
done
ls -l /tmp/list.txt
Вы также можете убедиться, что используете оболочку Bash (или связанную с ней), набрав «echo $ SHELL». Я думаю, что CSH и TCSH используют немного другую семантику для этого цикла.
while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
Если вы используете linux и у вас установлены inotify-tools, вы можете сделать это:
file=/tmp/list.txt
while [ ! -f "$file" ]
do
inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"
done
Это уменьшает задержку, вызванную спящим, при опросе каждые «x» секунд. Вы можете добавить больше событий, если считаете, что они необходимы.
--exclude
отфильтровывать имена файлов, но не --include
игнорировать все, кроме имени файла. В приведенной выше команде следует использовать -qq
аргумент, а не >&/dev/null
хотя.
--timeout
не частота проверок, не так ли? Суть inotifywait в том, что опроса нет
inotifywait
может зависнуть на неопределенное время, если файл создается непосредственно перед началом прослушивания событий.
У меня была такая же проблема, поставил! вне скобок;
while ! [ -f /tmp/list.txt ];
do
echo "#"
sleep 1
done
Кроме того, если вы добавите эхо внутри цикла, оно сообщит вам, попадаете ли вы в цикл или нет.
Я столкнулся с аналогичной проблемой, и это привело меня сюда, поэтому я просто хотел оставить свое решение для всех, кто испытывает то же самое.
Я обнаружил, что если бы я запустил cat /tmp/list.txt
файл, он был бы пустым, хотя я был уверен, что содержимое сразу помещается в файл. Оказывается, если я поставил sleep 1;
непосредственно перед этим, cat /tmp/list.txt
он работал, как ожидалось. Должна была быть задержка между временем создания файла и временем его записи, или что-то в этом роде.
Мой последний код:
while [ ! -f /tmp/list.txt ];
do
sleep 1;
done;
sleep 1;
cat /tmp/list.txt;
Надеюсь, это поможет кому-то сэкономить полчаса!
Как и у @ zane-hooper, у меня была аналогичная проблема с NFS. В параллельных / распределенных файловых системах задержка между созданием файла на одной машине и другой машиной, «видящей» его, может быть очень большой, поэтому я мог подождать целую минуту после создания файла до выхода из цикла while (и есть также последствие того, что он "видит" уже удаленный файл).
Это создает иллюзию, что сценарий «не работает» , в то время как на самом деле это файловая система бросает мяч.
Мне потребовалось время, чтобы понять, надеюсь, это кому-то сэкономит время.
PS Это также вызывает досадное количество ошибок "Обработчик устаревших файлов".
работает как с bash, так и с sh:
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.."
Вот версия с тайм-аутом, так что по прошествии некоторого времени цикл завершается с ошибкой:
# 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
делай это так
while true
do
[ -f /tmp/list.txt ] && break
sleep 2
done
ls -l /tmp/list.txt