Unix-way → Проверка условий в bash

При написании скриптов практически всегда имеется необходимость в проверке(ветвлении) каких либо процессов, другими словами — «делать это? или не делать? а если делать то что?». В интернетах достаточно много информации о операторах if|then|else которые и позволяют нам манипулировать ходом выполнения нашего скрипта. Тут главное понять «как это работает» все остальное приходит с практикой. Оговорюсь — не претендую на истину, потому что bash только изучаю, не один из примеров не несет сакраментального характера, все они сделаны для наглядности.

Операторы if|then и else

Операторы if|then проверяют код завершения списка команд на «успешное завершение(истина)» что в свою очередь означает «0», и если это так, то выполняет одну или более команд следующих за словом then. Если проверка возвращает «не успешное завершение (ложь)» что в свою очередь означает «1» выполняется else «иначе» если того требует условие. В завершении условия обязательно закрываем его «fi»!

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

Скобки

[ — является специальной встроенной командой test воспринимающей свои аргументы как выражение сравнения или файловую проверку [.....].

[[ — расширенный вариант от «[«, является зарезервированным словом, а не командой, его bash выполняет как один элемент с кодом возврата. Внутри «[[....]]» разрешается выполнение операторов &&, || которые приводят к ошибке в обычных скобках «[....]» тем самым вариант с двойной скобкой более универсален.

(( — является арифметическими выражениями, которое так же возвращают код 0. Тем самым такие выражения могут участвовать в операциях сравнения.

Приведу список логических операторов, которые используются для if|then|else:

  • строка пуста
    -z
  • строка не пуста
    -n
  • строки равны
    =, ( == )
  • строки неравны
    !=
  • равно
    -eq
  • неравно
    -ne
  • меньше
    -lt,(< )
  • меньше или равно
    -le,(<=)
  • больше
    -gt,(>)
  • больше или равно
    -ge,(>=)
  • отрицание логического выражения
    !
  • логическое «И»
    -a,(&&)
  • логическое «ИЛИ»
    -o,(||)


Конструкции простой проверки if|then

if условие; then
    команды
fi


другими словами

если  проверяемое_выражение_или_команды_верны;  то
   выполняем команды
закрываем если


Пример 1
#!/bin/bash

if echo Тест; then
    echo 0
fi


Часто встречается в скриптах проверка — «существует ли файлы или каталоги» на их примере покажу работу

пример 2

#!/bin/bash

if [ -f $HOME/.bashrc ]; then
    echo "Файл существует!"
fi


где
  • $HOME/.bashrc — путь до файла
  • echo — печатает сообщение в консоль

Пример 3

#!/bin/bash

if [[ -f $HOME/.bashrc && -f  /usr/bin/nano ]]; then
    echo "Все впорядке, можно редактировать!"
fi

где
  • && — логическое «и», если первый путь «истина» проверяем второй, если он тоже «истина», то выполняем команды (echo)
  • -f — ключ проверки на существования файла (о них чуть ниже)


Конструкции простой проверки if|then|else

if условие; then
    команды 1
else
    команды 2
fi

другими словами

если проверяемое_выражение_или_команды_верны;  то
   команды 1
иначе
   команды 2
закрываем если


Пример 4

Возможно не лучший пример, нас интересует именно ответ 0 или 1. В результате печатается в консоль «Тест» и «0» потому что команда «echo Тест» успешна и это «истина».
#!/bin/bash

if echo Тест; then
    echo 0
else
    echo 1
fi


Намерено допустите ошибку изменив echo, в результате получите «1» и сообщение о том что «команда eho не существует» и это «ложь».

#!/bin/bash

if eho Тест; then
    echo 0
else
    echo 1
fi


Примеры «существуют ли файл?»

Пример 5

Если файл bashrc существует, то печатает в консоль «Файл существует!», иначе печатает «Файл не существует!»

#!/bin/bash

if [ -f "$HOME/.bashrc" ]; then
    echo "Файл существует!"
else
  echo "Файл не существует!"
fi


Поиграйте с именем проверяемого файла

Пример 5

#!/bin/bash

if [[ -f "$HOME/.bashrc" && -f "/usr/bin/nano" ]]; then
    echo "Все в порядке, можно редактировать!"
  else
  echo "Ошибка!"
fi


Ключи к фалам и каталогам
[ -ключ "путь" ]


[ -e "путь каталогу_или_файлу"] #- существует ли файл или каталог?
[ -r "путь к файлу/каталогу"] #-  доступен ли файл/каталог для чтения?
[ -f "путь к файлу/каталогу"] #- существует ли файл?
[ -d "путь к каталогу"] #- существует ли каталог?


Полное описание возможных применений различных скобок, правильное разставление кавычек уходит далеко от темы потому могу посоветовать обратится к руководству Advanced Bash Scripting

Арифметика

Пример 6

Если оператор > использовать внутри [[….]], он рассматривается как оператор сравнения строк, а не чисел. Поэтому операторам > и < для сравнения чисел лучше заключить в круглые скобки.

Используем круглые скобки для математического сравнение. Если «3» меньше «6» печатаем «Да».
#!/bin/bash

if (( 3 < 6)); then
    echo Да
fi


Пример 7

Использование команды test коей является квадратные скобки. Если «3» меньше «6» печатаем «Да».

#!/bin/bash

if [ 3 -lt 6 ]; then
    echo Да
fi


Можно использовать и двойные квадратные скобки, как вы наверно уже поняли это расширенный вариант команды test эквивалентом которой является «[ ]». Если «3» меньше «6» печатаем «Да».

#!/bin/bash
if [[ 3 -lt 6 ]]; then
    echo Да
fi


Пример 8

Используем двойные квадратные скобки, потому что применяем оператор «&&». Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если оно тоже 2=2 (истина), печатаем «Верно»

#!/bin/bash

a="2"
b="2"
if [[ 2 = "$a" && 2 = "$b" ]] ; then
    echo Верно
else
    echo Не верно
fi


Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если переменная «b» не равна двум (лож), печатаем «Не верно»

#!/bin/bash

a="2"
b="3"
if [[ 2 = "$a" && 2 = "$b" ]] ; then
    echo Верно
else
    echo Не верно
fi


Можно конечно сделать проще, нам главное понять принцип if|then и else, не стесняйтесь менять подставляя свои значения.

Вложение нескольких проверок

Bash позволяет вкладывать в блок несколько блоков

#!/bin/bash

if [ Условие 1 ]; then
  if [ Условие 2 ]; then
    Команда 1
  else
    Команда 2
  fi
else
  Команда 3
fi


Построения многоярусных конструкций

Для построения многоярусных конструкции, когда необходимо выполнять множество проверок лучше использовать elif — это краткая форма записи конструкции else if.

if [ Условие 1 ]; then
   Команда 1
   Команда 2
elif [ Условие 2 ]; then
   Команда 3
   Команда 4
else
   Команда 5
fi
  • avatar
  • itshnic
  • 54372
  • +23
  • 11 апреля 2011, 20:02

Комментариум (4)

RSS свернуть / развернуть
+
+6
avatar

StranNik

  • 12 апреля 2011, 07:14

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/makenskiy/www/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Весьма полезно, спасибо!

Хотелось бы побольше примеров, например я долго искал как можно использовать в условиях результаты выполнения команд:
#!/bin/bash
var=`ps afx | grep -U worker.php ` # Все процессы с именем worker
output=$(grep -e 'first' <<<"$var" | wc -l) # Отсеиваем нужный процесс
if test "$output" -ge "1" ; then # Если больше или равен 1 
    echo "OK - $output"	
else
    /usr/bin/php /var/www/worker.php first & # Иначе запускаем
fi
+
+5
avatar

pashtuun

  • 12 апреля 2011, 12:45

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/makenskiy/www/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Добавил в избранное, пригодится, спасибо!
+
+4
avatar

makenskiy

  • 12 апреля 2011, 18:16

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/makenskiy/www/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Тоже об этом хотел пост делать, спасибо! Еще бы о функциях написать.
+
+2
avatar

Anonymous

  • 16 апреля 2011, 22:55

  • Warning: Smarty error: unable to read resource: "cmtedit_button.tpl" in /home/makenskiy/www/itbuben.org/public_html/engine/lib/external/Smarty-2.6.19/libs/Smarty.class.php on line 1092
Вставь в пост http://www.easyfoto.ru/20110416185448039.gif картинку наглядную

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.