практически любой язык программирования включает в себя условные операторы, предназначенные для проверки условий, чтобы выбрать тот или иной путь развития событий в зависимости от этих условий. В Bash, для проверки условий, имеется команда test, различного вида скобочные операторы и условный оператор if/then.
7.1. Конструкции проверки условий
Оператор if/then проверяет — является ли код завершения списка команд 0 (поскольку 0 означает «успех» ), и если это так, то выполняет одну, или более, команд, следующие за словом then.
Существует специальная команда — [ (левая квадратная скобка). Она является синонимом команды test, и является встроенной командой (т.е. более эффективной, в смысле производительности). Эта команда воспринимает свои аргументы как выражение сравнения или как файловую проверку и возвращает код завершения в соответствии с результатами проверки (0 — истина, 1 — ложь).
Начиная с версии 2.02, Bash предоставляет в распоряжение программиста конструкцию [[ . ]] расширенный вариант команды test , которая выполняет сравнение способом более знакомым программистам, пишущим на других языках программирования. Обратите внимание: [[ — это зарезервированное слово, а не команда.
Bash исполняет [[ $a -lt $b ]] как один элемент, который имеет код возврата.
Круглые скобки (( . )) и предложение let . так же возвращают код 0 , если результатом арифметического выражения является ненулевое значение. Таким образом, арифметические выражения могут учавствовать в операциях сравнения.
Условный оператор if проверяет код завершения любой команды, а не только результат выражения, заключенного в квадратные скобки.
Оператор if/then допускает наличие вложенных проверок.
Это детальное описание конструкции «if-test» любезно предоставлено Stephane Chazelas.
Пример 7-1. Что есть «истина»?
Упражнение. Объясните результаты, полученные в Пример 7-1.
Когда if и then располагаются в одной строке, то конструкция if должна завершаться точкой с запятой. И if , и then — это зарезервированные слова. Зарезервированные слова начинают инструкцию, которая должна быть завершена прежде, чем в той же строке появится новая инструкция.
Else if и elif
elif — это краткая форма записи конструкции else if . Применяется для построения многоярусных инструкций if/then .
Конструкция if test condition-true является точным эквивалентом конструкции if [ condition-true ], где левая квадратная скобка [ выполняет те же действия, что и команда test. Закрывающая правая квадратная скобка ] не является абсолютно необходимой, однако, более новые версии Bash требуют ее наличие.
Команда test — это встроенная команда Bash, которая выполняет проверки файлов и производит сравнение строк. Таким образом, в Bash-скриптах, команда test не вызывает внешнюю ( /usr/bin/test) утилиту, которая является частью пакета sh-utils . Аналогично, [ не производит вызов утилиты /usr/bin/[, которая является символической ссылкой на /usr/bin/test.
Пример 7-2. Эквиваленты команды test — /usr/bin/test, [ ] , и /usr/bin/[
Конструкция [[ ]] более универсальна, по сравнению с [ ] . Этот расширенный вариант команды test перекочевал в Bash из ksh88 .
Внутри этой конструкции не производится никакой дополнительной интерпретации имен файлов и не производится разбиение аргументов на отдельные слова, но допускается подстановка параметров и команд.
Конструкция [[ . ]] более предпочтительна, нежели [ . ], поскольку поможет избежать некоторых логических ошибок. Например, операторы && , || , и > внутри [[ ]] вполне допустимы, в то время как внутри [ ] порождают сообщения об ошибках.
Строго говоря, после оператора if, ни команда test, ни квадратные скобки ( [ ] или [[ ]] ) не являются обязательными.
Инструкция «if COMMAND» возвращает код возврата команды COMMAND.
Точно так же, условие, находящееся внутри квадратных скобок может быть проверено без использования оператора if.
Внутри (( )) производится вычисление арифметического выражения. Если результатом вычислений является ноль, то возвращается 1 , или «ложь» . Ненулевой результат дает код возврата 0 , или «истина» . То есть полная противоположность инструкциям test и [ ] , обсуждавшимся выше.
Пример 7-3. Арифметические выражения внутри (( ))
Источник
Оператор if else в Bash
В этом руководстве мы познакомим вас с основами оператора if Bash и покажем, как использовать его в сценариях оболочки.
Принятие решений — одна из самых фундаментальных концепций компьютерного программирования. Как и в любом другом языке программирования, if..else if , if..else , if..elif..else и вложенные if в Bash могут использоваться для выполнения кода на основе определенного условия.
Оператор if
Bash, if условные выражения могут иметь разные формы. Самый простой оператор if принимает следующую форму:
Оператор if начинается с ключевого слова if за которым следует условное выражение и ключевое слово then . Заявление заканчивается ключевым словом fi .
Если TEST-COMMAND значение True , STATEMENTS выполняется. Если TEST-COMMAND возвращает False , ничего не происходит, STATEMENTS игнорируется.
В общем, рекомендуется всегда делать отступ в коде и разделять блоки кода пустыми строками. Большинство людей предпочитают использовать отступы с четырьмя или двумя пробелами. Отступы и пустые строки делают ваш код более читабельным и организованным.
Давайте посмотрим на следующий пример скрипта, который проверяет, больше ли заданное число 10:
Сохраните код в файл и запустите его из командной строки:
Скрипт предложит вам ввести номер. Если, например, вы введете 15, test команда будет иметь значение true потому что 15 больше 10, и будет выполнена команда echo внутри предложения then .
Оператор if else
Оператор if..else Bash принимает следующую форму:
Если TEST-COMMAND оценивается как True , STATEMENTS1 будет выполнен. В противном случае, если TEST-COMMAND возвращает значение False , то STATEMENTS2 будет выполнено. В заявлении может быть только одно предложение else .
Давайте добавим предложение else в предыдущий пример сценария:
Если вы запустите код и введете число, сценарий напечатает другое сообщение в зависимости от того, больше ли число / равно 10.
Оператор if elif else
Оператор if..elif..else Bash имеет следующую форму:
Если TEST-COMMAND1 вычисляет значение True , то STATEMENTS1 будет выполнено. Если TEST-COMMAND2 вычисляет значение True , то STATEMENTS2 будет выполнено. Если ни одна из тестовых команд не оценивается как True , выполняется STATEMENTS2 .
В операторе может быть одно или несколько предложений elif . Предложение else является обязательным.
Условия оцениваются последовательно. Как только условие возвращает True остальные условия не выполняются, и управление программой перемещается в конец операторов if .
Добавим в предыдущий скрипт предложение elif :
Вложенные операторы if
Bash позволяет гнездо , if заявления в if заявления. Вы можете разместить несколько операторов if внутри другого оператора if .
Следующий сценарий предложит вам ввести три числа и напечатает наибольшее число из трех.
Вот как будет выглядеть результат:
Несколько условий
Логические операторы OR и AND позволяют использовать несколько условий в операторах if .
Вот еще одна версия скрипта для печати наибольшего числа из трех. В этой версии вместо вложенных операторов if мы используем логический оператор AND ( && ).
Операторы тестирования
В Bash команда test принимает одну из следующих синтаксических форм:
Чтобы сделать сценарий переносимым, лучше использовать старую команду test [ которая доступна во всех оболочках POSIX. Новая обновленная версия test команды [[ (двойные скобки) поддерживается в большинстве современных систем, использующих Bash, Zsh и Ksh в качестве оболочки по умолчанию.
Чтобы отрицать тестовое выражение, используйте оператор логического NOT ( ! ). При сравнении строк всегда используйте одинарные или двойные кавычки, чтобы избежать проблем с разделением слов и подстановкой слов.
Ниже приведены некоторые из наиболее часто используемых операторов:
-n VAR — Истинно, если длина VAR больше нуля.
-z VAR — Истинно, если VAR пуста.
STRING1 = STRING2 — Истина, если STRING1 и STRING2 равны.
STRING1 != STRING2 — Истина, если STRING1 и STRING2 не равны.
INTEGER1 -eq INTEGER2 — Истина, если INTEGER1 и INTEGER2 равны.
INTEGER1 -gt INTEGER2 — Истина, если INTEGER1 больше INTEGER2 .
INTEGER1 -lt INTEGER2 — Истина, если INTEGER1 меньше INTEGER2 .
INTEGER1 -ge INTEGER2 — Истинно, если INTEGER1 больше или больше INTEGER2.
INTEGER1 -le INTEGER2 — Истинно, если INTEGER1 меньше или меньше INTEGER2 .
-h FILE — Истина, если FILE существует и является символической ссылкой.
-r FILE — Истинно, если FILE существует и доступен для чтения.
-w FILE — Истина, если FILE существует и доступен для записи.
-x FILE — Истина, если FILE существует и является исполняемым.
-d FILE — Истина, если FILE существует и является каталогом.
-e FILE — Истина, если FILE существует и является файлом, независимо от типа (узел, каталог, сокет и т. д.).
-f FILE — Истина, если FILE существует и является обычным файлом (не каталогом или устройством).
Выводы
Операторы if , if..else и if..elif..else позволяют вам управлять потоком выполнения сценария Bash, оценивая заданные условия.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Источник
LiveStreet
Bash → Язык командного интерпретатора bash. Part 4. «Условные операторы»
Данный топик является четвертым топиком цикла «Язык командного интерпретатора bash». Он будет повествовать о таких управляющих структурах языка, как условные операторы. Но перед тем, как перейти к их описанию, необходимо остановиться на некоторых нюансах, которые сделают рассмотрение нижеизложенного материала более понятным. Во-первых, разберём, что такое список команд. Список команд – это одиночная команда, конвейер или последовательность команд/конвейеров, разделённых одним из следующих операторов: «;», «&&», «||», завершённая точкой с запятой. ; — оператор последовательного выполнения нескольких команд. Каждая последующая команда начинает выполняться только после завершения предыдущей (неважно, успешного или нет); && — оператор выполнения команды только после успешного выполнения предыдущей; || — оператор выполнения команды только после ошибочного выполнения предыдущей. Кодом успешного завершения является 0, а ошибочного — не ноль (зависит от типа ошибки). Не нужно путать с обычными языками программирования, когда 1 является аналогом true, а 0 – false. Теперь можно приступить к непосредственному рассмотрению условных операторов.
Оператор вариантов case
Общий синтаксис оператора case:
case значение in шаблон1) список1;; шаблон2 | шаблон3) список2;; esac
Логическая последовательность выполнения оператора case: а) ищется первый шаблон, совпадающий со значением; б) если он найден, выполняется соответствующий ему список команд, завершённый «;;»; в) управление передаётся операторам, следующим за конструкцией case. Шаблон и список разделяются символом «)». Одному списку команд может соответствовать несколько условий, тогда их нужно разделять символом «|». В шаблонах можно использовать символы «*», «?», «[ ]», о которых было рассказано во втором топике цикла. С их помощью можно реализовать инструкцию, действующую как default в операторе switch таких языков, как C, PHP. Приведу пример использования case:
Ещё один пример использования конструкции case:
Условный оператор if
Общий синтаксис оператора if:
if список1 then список2 [elif список3 then список4] [else список5] fi
Квадратные скобки здесь указывают на необязательные конструкции. Логическая последовательность выполнения оператора case: а) выполняется список1; б) если он выполнен без ошибок, выполняется список2. В противном случае выполняется список3, и если он завершается без ошибок – список4. Если же и список3 возвращает код ошибки, выполняется список5; в) управление передаётся операторам, следующим за конструкцией if. Приведу пример использования if:
Когда if и then располагаются в одной строке, то конструкции if и then должны завершаться точкой с запятой. Например:
Теперь, зная о возможни располагать if и then в одной строке, перепишем вышеуказанный пример:
Оператор test и условные выражения
В вышеприведённом примере вместо анализа кода завершения использована проверка условия. Две формы такой проверки эквивалентны: встроенная команда test и [условие]. Например, для проверки существования файла нужно написать:
Если используются квадратные скобки, они обязательно должны быть отделены друг от друга пробелом, потому что «[» – это название команды, а «]» – это обязательный последний аргумент её завершения. В случае успешной проверки условия, возвращается 0, а в случае ложности – код ошибки 1. Команда test может проверять строку на пустоту. Непустая строка приводит к коду завершения 0. Пуста, соответственно – 1. Например:
Конструкция «[[ ]]» более универсальна, по сравнению с «[ ]». Этот расширенный вариант команды test. Внутри этой конструкции не производится никакой дополнительной интерпретации имен файлов и не производится разбиение аргументов на отдельные слова, но допускается подстановка параметров и команд. Например:
Конструкция «[[ ]]» более предпочтительна, нежели «[ ]», поскольку поможет избежать некоторых логических ошибок. Например, операторы «&&», «||», » » внутри «[[ ]]» вполне допустимы, в то время как внутри «[ ]» порождают сообщения об ошибках. Конструкция «(( ))» позволяет производить вычисление арифметических выражений внутри неё. Если результатом вычислений является ноль, то возвращается код ошибки. Ненулевой результат вычислений даёт код возврата 0. То есть полная противоположность инструкциям test и «[ ]», обсуждавшимся выше. Оператор if позволяет допускать наличие вложенных проверок:
Условные выражения можно комбинировать с помощью обычных логических операций: ! – отрицание; –a – логическое И; –o – логическое ИЛИ.
Элементарные условные выражения для файлов: -e — файл существует; -f — обычный файл (не каталог и не файл устройства); -s — ненулевой размер файла; -d — файл является каталогом; -b — файл является блочным устройством (floppy, cdrom и т.п.); -c — файл является символьным устройством (клавиатура, модем, звуковая карта и т.п.); -p — файл является каналом; -h — файл является символической ссылкой; -L — файл является символической ссылкой; -S — файл является сокетом; -t — файл связан с терминальным устройством; -r — файл доступен для чтения (пользователю, запустившему сценарий); -w — файл доступен для записи (пользователю, запустившему сценарий); -x — файл доступен для исполнения (пользователю, запустившему сценарий); -g — (sgid) флаг для файла или каталога установлен; -u — (suid) флаг для файла установлен; -k — флаг sticky bit установлен; -O — вы являетесь владельцем файла; -G — вы принадлежите к той же группе, что и файл; -N — файл был модифицирован с момента последнего чтения; файл1 -nt файл2 – файл1 более новый, чем файл2; файл1 -ot файл2 – файл1 более старый, чем файл2; файл1 -ef файл2 – файл1 и файл2 являются «жесткими» ссылками на один и тот же файл.
Элементарные условные выражение для сравнения строк: -z строка – длина строки равна 0; -n строка – длина строки не равно 0; строка1 == строка2 – строки совпадают (аналог “=”); строка1 !== строка2 – строки не совпадают (аналог “!=”); строка1 строка2 – строка1 следует за строкой2 в лексикографическом порядке. Арифметическое условное выражение имеет формат: аргумент1 операция аргумент2, где аргументами являются целые числа, и допустимы следующие операции: -eq – равно; -ne – не равно; -lt – меньше; -le – меньше или равно; -gt – больше; -ge – больше или равно; — больше (внутри двойных круглых скобок); >= — больше или равно (внутри двойных круглых скобок).
Перепишем предыдущий пример с использованием оператора if:
В следующем топике я продолжу рассматривать управляющие структуры командного интерпретатора bash. А именно, будут рассмотрены операторы циклов. А сейчас жду комментариев и критики :).
UPD: Спасибо пользователю aonick за его замечания и критику.