LinuxForum.Fans
Тема

проверка условия в сценарии работает не корректно

Автор: OMIXO 18 сообщений 4348 просмотров
#301613

Здравствуйте.

Такая вот проблема:
Есть сценарий, в котором условие сравнивающее два числа между собой работает В ЭТОМ СЦЕНАРИИ наоборот, а из командной строки - правильно.
Не могу найти проблему.

Сценарий:

text
#! /bin/sh
# untilmonit

# Получаем столбец со значениями процентов и удаляем знак % из df LOOK_OUT=`df | grep /dev/sda5 | awk ' {print $5}' | sed 's/%//g'` echo $LOOK_OUT

until [ "$LOOK_OUT" -gt "90" ] # сравнение (-gt <первое число больше второго> и -lt <первое число меньше второго>) почему-то работает наоборот??? из командной строки работает правильно??? #[ $LOOK_OUT -gt 90 ] #test $LOOK_OUT -gt 90 do echo "Диск файловой системы sda5 почти полный" #| mail root exit 0 done

Обратите внимание, что я в сценарии по-разному пытался задавать условие, но результат тот же.

Результат выполнения сценария:

text
mix@bigdesk:/media/sda5/work/loop/until$ ./u*m*
66
Логи файловой системы (/logs) почти полны

66 меньше 90, значит сообщение "Логи файловой системы (/logs) почти полны" не должно появиться.

Спасибо за помощь.

#301614

Прошу прощения. Немножко подправил сценарий, а результат его выполнения скопировал старый.

Результат выполнения сценария такой:

text
mix@bigdesk:/media/sda5/work/loop/until$ ./u*m*
66
Диск файловой системы sda5 почти полный
#301616
"OMIXO" написал:
#! /bin/sh

Пробела после «!» быть не должно.
В скрипте поменяйте until на while.

#301619

А зачем там вообще while/until? Имелся в виду обычный if?

#301622
"bormant" написал:
А зачем там вообще while/until? Имелся в виду обычный if?

if — одноразовая проверка условия, с помощью while/until можно сделать проверку на протяжении времени.

#301627
"OMIXO" написал:
66 меньше 90, значит сообщение "Логи файловой системы (/logs) почти полны" не должно появиться.

Читайте внимательнее:

text

$ help until
until: until COMMANDS; do COMMANDS; done
    Execute commands as long as a test does not succeed.

#301850
Lupo Alberto написал:
[quote="bormant"]А зачем там вообще while/until? Имелся в виду обычный if?

if — одноразовая проверка условия, с помощью while/until можно сделать проверку на протяжении времени.[/quote]
Так про то и говорю, что толку сравнивать одно и то же значение несколько раз, если получение значения вынесено за цикл, внутри тела цикла значение не меняется. Или как в том анекдоте, после шестимиллиардной попытки сервер согласился с паролем мао?

#301891

1)

"Lupo Alberto" написал:
Пробела после «!» быть не должно.В скрипте поменяйте until на while.

Спасибо за замечание обязательно учту его. Может по каким-то классическим канонам написания сценариев там пробела и не должно быть, но в моей системе все запускаемые сценарии абсолютно не чувствительны к наличию или отсутствию пробела в этом месте.

2)

"bormant" написал:
А зачем там вообще while/until?

Если вы внимательно прочитали сценарий, то должны были заметить, что он измеряет свободное пространство диска и при преодолении некоего "критического" значения сообщает, что места почти не осталось. А т. к. место на диске меняется с течением времени, то и контролировать этот параметр нужно постоянно.

3)

"-=Serj=-" написал:
Читайте внимательнее:$ help until
until: until COMMANDS; do COMMANDS; done
Execute commands as long as a test does not succeed.
"bormant" написал:
что толку сравнивать одно и то же значение несколько раз, если получение значения вынесено за цикл, внутри тела цикла значение не меняется

Извините, но я так и не понял на что вы хотели обратить мое внимание. Если можно объясните поподробнее.

#301893

4)
В конце концов, не имеет значение при каком операторе цикла выполняется проверка условия. Влюбом случае она должна выполняться кооректно. И это уже вопрос принципа. :P
Я так и не понял где ошибка в сценарии?
У вас у всех он работает так же?

#301895
"OMIXO" написал:
А т. к. место на диске меняется с течением времени, то и контролировать этот параметр нужно постоянно.

Тогда надо было как-то так:

text

while :
do
    if  ПРОВЕРКА;
         then
            СКРИПТ_1
         else
           СКРИПТ_2
    fi

sleep 60

done

Но всё это о-о-очень «велосипедостроительно»! ;)
Гляньте man watch и man crontab на предмет периодического запуска каких-либо команд.

Если вам по каким-то причинам не нравятся имеющиеся графические мониторы дискового пространства, попробуйте glances — средство простого мониторинга системы, как локальной, так и удалённой.

#301896
"OMIXO" написал:
Я так и не понял где ошибка в сценарии?

until ⇒ while

#301903
"Lupo Alberto" написал:
Но всё это о-о-очень «велосипедостроительно»! ........

Я понимаю, что этот сценарий, возможно, не имеет практического интереса.
Но тут уже чисто академический интерес. Почему это вдруг в данном сценарии test работает некорректно c until.

Тут уже не интересно чем заменить until или вообще весь сценарий. Тут важно понять это ошибка в написании сценария (и если да, то где именно) или это баг какой-то из команд (until, test).

Может ли кто-нибудь запустить у себя этот сценарий и написать как у вас работает команда test корректно или нет.

У меня на работе Linux стоит в VirtualBoxe гостевой системой, а дома - основной. И там и там сценарий работает одинаково не корректно.
Похоже это баг???

#301907
"OMIXO" написал:
Похоже это баг???

http://rus-linux.net/MyLDP/BOOKS/abs-guide/flat/abs-book.html#LOOPS


Оператор while проверяет условие перед началом каждой итерации и если условие истинно (если код возврата равен 0), то управление передается в тело цикла.


Оператор цикла until проверяет условие в начале каждой итерации, но в отличие от while итерация возможна только в том случае, если условие ложно.
#301951
OMIXO написал:

2)
[quote="bormant"]А зачем там вообще while/until?

Если вы внимательно прочитали сценарий, то должны были заметить, что он измеряет свободное пространство диска и при преодолении некоего "критического" значения сообщает, что места почти не осталось. А т. к. место на диске меняется с течением времени, то и контролировать этот параметр нужно постоянно.
[/quote]Это далеко не так.

OMIXO написал:

3)
[quote="bormant"]что толку сравнивать одно и то же значение несколько раз, если получение значения вынесено за цикл, внутри тела цикла значение не меняется

Извините, но я так и не понял на что вы хотели обратить мое внимание. Если можно объясните поподробнее.[/quote]Вы до цикла получили в переменную размер свободного места. Потом вы это число пытаетесь сравнивать несколько раз с числом 90, повторного вычисления размера свободного места не производится. Смысла в таком испозовании цикла нет никакого.

#302164

Всем большое спасибо за помощь.
Благодаря этому непрактичному и непонятному сценарию разобрался в работе цикла until. *JOKINGLY*
Наверное это и есть главное назначение данного сценария. :D

#302168

кстати по указанной ссылке:

"Lupo Alberto" написал:

есть пример использования оператора цикла until:

text
#!/bin/bash

until [ "$var1" = end ] # Проверка условия производится в начале итерации. do echo "Введите значение переменной #1 " echo "(end - выход)" read var1 echo "значение переменной #1 = $var1" done

exit 0

Почему exit 0 находится в самом конце сценария? Мне кажется было лы логичнее расположить его в теле цикла перед done (один раз задал значение переменной #1 и до свидания)?
Или в этом есть свой тайный смысл???

#302169

Правда зачем тогда вообще нужен цикл?
А если "end" обрывает цикл, тогда значение переменной всегда будет end?
Дилемма....

Хотя скорее этот сценарий (как и мой) только для того, чтобы показать как работает until.

Короче поговорил сам с собой. Сам спросил сам ответил.

#302170
"OMIXO" написал:
Или в этом есть свой тайный смысл???

Если вы расположите exit 0 в теле цикла, то он отработает ровно один раз. В данном случае exit 0 означает успешное, т.е., без ошибок, завершение работы, потому и в конце скрипта.

Войдите или зарегистрируйтесь, чтобы ответить.