LINUX.ORG.RU

Bash не выходит из цикла WHILE

 , ,


1

1

Всех приветствую! Помогите плиз. Нужен был скриптик для очистки места с сортировкой. скрипт проверяет место, если его нет, то запускается цикл WHILE ищутся файлы, сортируются удаляются, проверяется место, если мало продолжается цикл. После достижения нужного значения цикл должен прерываться. Но этого не происходит, скрипт уходит в бесконечный цикл. Помогите разобраться.

 
#!/bin/bash
cd /opt
i=`df -kP | grep "/dev/sdb1" | awk '{print $4}'`
echo "space for disk= $i KB"
while [[ $i -lt 1024000 ]]
do find /opt/ -name "*.log" -mtime +1 -and -type f | sort -r | tail -n1 | xargs -i rm '{}'
if [[ $i -eq 1024000 ]];
then
break
fi
done
echo "All DONE" 

Перемещено shell-script из linux-org-ru

А как он у тебя вообще выйдет, если условие с break не будет выполнено никогда?

Тем паче, что переменная i вообще в цикле не меняется!

Eddy_Em ☆☆☆☆☆ ()
Последнее исправление: Eddy_Em (всего исправлений: 1)
fi
done

Вот тут вставляешь echo i=$i и смотришь на причину своих бед.

П.С. Блин, да ты в теле цикла i не меняешь, как он может вообще завершиться?!

torvn77 ★★★★★ ()
Последнее исправление: torvn77 (всего исправлений: 2)

-lt на -le поменяй в условии while

cocucka ★★★★★ ()
Ответ на: комментарий от in_dance

if [[ $i -eq 1024000 ]];

Пытался таким способом проверить наличие большего места, чем значение, что бы прервать цикл((( , но судя из вышесказанных коментов, не уверен…

igorian1901 ()
Ответ на: комментарий от torvn77

script

Спасибо всем за подсказки. Понял из за чего цикл не завершался. Он гонял нулевое значение и не мог выйти из цикла. Прописав переменную в while все заработало как надо )))

#!/bin/bash
cd /opt
i=`df -kP | grep "/dev/sdb1" | awk '{print $4}'`
echo "space for disk= $i KB"
while [[ $i -lt 1024000 ]]
do find /opt/ -name "*.log" -mtime +1 -and -type f | sort -r | tail -n1 | xargs -i rm '{}'
i=`df -kP | grep "/dev/sdb1" | awk '{print $4}'`
if [[ $i -eq 1024000 ]];
then
break
fi
echo i=$i
done
echo "All DONE" 
igorian1901 ()
Ответ на: script от igorian1901

Что самое интересное никто кроме меня из участников треда не смог заметить истинную причину твоих затруднений, а ведь вместе с тем я простой курье-грузчик, а вовсе не программист, ни админ и даже не аникей(хотя и мог бы потянуть такую работу).

torvn77 ★★★★★ ()
Ответ на: script от igorian1901

Re: script

Спасибо всем за подсказки. Понял из за чего цикл не завершался. Он гонял нулевое значение и не мог выйти из цикла. Прописав переменную в while все заработало как надо )))

Ну от «как надо» у вас получилось весьма отдаленно. Во-первых, и это самое главное, ваш поиск и удаление логов от параметра цикла никак не зависит, потому цикл будет крутиться либо бесконечно, если удаление логов один раз будет недостаточно для получения нужного вам свободного объёма либо ровно один раз. То есть правильнее было б начинать с более старых логов, и, если этого недостаточно, то повышать дату в цикле ближе к сегодняшней.

Во-вторых, некрасиво писать одно и тоже до и внутри цикла, циклы же для того и существуют, чтобы делать однотипные действия по условию.

В-третьих, break из цикла создан для дополнительного преждевременного выхода из тела. У вас ни то ни другое не происходит и потому полностью лишнее.

vodz ★★★★★ ()
Ответ на: комментарий от torvn77

Что самое интересное никто кроме меня из участников треда не смог заметить истинную причину т

Чо врать то, первый же комментатор написал всё правильно.

vodz ★★★★★ ()
df -kP | grep "/dev/sdb1" | awk '{print $4}'

вызов grep лишний, awk прекрасно справляется с поиском:

df -kP | awk '/sdb1/{print $4}'

и я бы порядок вычислений полностью изменил

cd /opt
while true; do
 i=`df -kP | awk '/sdb1/{print $4}'`
 echo "space for disk= $i KB"
 if [[ $i >= 1024000 ]]; then break; fi
 
 find /opt/ -name "*.log" -mtime +1 -and -type f | sort -r | tail -n1 | xargs -i rm '{}'
done
sigurd ★★★★★ ()
Последнее исправление: sigurd (всего исправлений: 3)
Ответ на: комментарий от anonymous

Жа нет, я просто читал только последующие комментарии. Ну тоже шляпа, не отказывсь.

torvn77 ★★★★★ ()
while [[ $i -lt 1024000 ]]
if [[ $i -eq 1024000 ]]

Если уж /bin/bash в шебанге, тогда и башизмы во все поля:

while [[ $i < 1024000 ]]
if [[ $i == 1024000 ]]
akk ★★★★★ ()
Ответ на: комментарий от akk

тогда и башизмы во все поля

Прочтите документацию и не позорьтесь

vodz ★★★★★ ()
Ответ на: комментарий от theNamelessOne

Ежедневно — только по праздникам. Обычно же по настроению, где-то раз в 2-4 дня.

Eddy_Em ☆☆☆☆☆ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.