практически любой язык программирования включает в себя условные операторы, предназначенные для проверки условий, чтобы выбрать тот или иной путь развития событий в зависимости от этих условий. В 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 в Bash: от новичка до профессионала
Перевод статьи «Bash If Statements: Beginner to Advanced».
Bash это интересный язык. Изначально он был создан для интерактивного использования в командной строке, главным образом в REPL (Read-Evaluate-Print-Loop – «цикл чтение-вычисление-вывод») для работы над одной командой пользователя за раз.
Этот язык спроектирован для существенной, но при этом лаконичной обработки простого текста. У этого есть побочный эффект: немного сложнее выполнять вещи, которые не являются интерактивными или связанными с текстом, например, арифметические вычисления, контроль потоков и манипуляции переменными.
В этой статье мы рассмотрим одну из немного запутанных тем: if-предложения. Мы погрузимся в их работу и узнаем, как более точно использовать ее механизмы.
Примечание: эта статья о Bash, однако большая часть всего сказанного здесь применима к Zsh и другим оболочкам. Некоторые из вещей несовместимы с POSIX.
Основы
If-предложения в Bash очень похожи на аналогичные в других языках. Они следуют базовой форме:
Дополнительный синтаксис в виде слова then , а также слегка странное закрывающее ключевое слово fi придает предложению немного экзотический вид, но в основе все то же самое, что и в других языках:
Если (if) что-то является истиной, тогда (then) выполни вот это. В противном случае проверяй другие условия по порядку и делай то же самое. Если ни одно из условий не сработало, выполни последнее указание.
Вы можете отбросить одну или все ветки elif , а также ветку else , если в них нет нужды!
Булевы операторы ! (нет), && (и), || (или) могут использоваться для комбинирования выражений, как и в других языках.
Но здесь есть нечто запутанное. Порой вам встретятся двойные квадратные скобки, как в примере выше. А порой они будут одинарными.
Иногда могут быть и круглыми!
И временами их вообще не будет!
Как знать, какие именно скобки нужно использовать? Когда каждый из вариантов является подходящим? Почему какие-то из них не будут работать в определенных случаях?
Что происходит на самом деле
Есть магические слова, которые стоят за работой if в Bash: коды выхода. Вот шаблон того, что происходит на самом деле:
Все верно: содержимое сразу после if может быть вообще любой командой, если она дает код выхода (а практически всегда так и бывает). Если команда возвращает код выхода 0 (в Bash это код успешно выполненной операции), тогда запускается код внутри ветки then . В противном случае Bash переходит к следующей ветке и делает новую попытку.
Но, погодите, это означает, что…
Ага. «[» это команда. Это, собственно, синтаксический сахар для встроенной команды test , которая проверяет и сравнивает переданные ей аргументы. «]» это на самом деле аргумент для команды [ , который говорит ей прекратить проверять аргументы!
В этом примере команда [ принимает в качестве аргументов «$price» (переменная сразу же заменяется ее значением), -lt , 10 и ] .
Теперь, с учетом того что -lt , -gt и похожие числовые сравнения на самом деле являются аргументами, не кажется ли странный синтаксис немного более осмысленным? Они выглядят, как опции! Вот почему знаки > и странно себя ведут внутри одинарных квадратных скобок: Bash думает, что вы пытаетесь перенаправить input или output внутри команды!
Как насчет двойных квадратных скобок?
Довольно странно, однако [[ двойные квадратные скобки ]] и (( двойные круглые скобки )) это не совсем команды. Они представляют собой ключевые слова языка Bash, в результате чего они ведут себя немного более предсказуемо. Тем не менее, в зависимости от своего содержимого, они по-прежнему возвращают код выхода.
[[ Двойные квадратные скобки ]] работают в целом так же, как и [ одинарные квадратные скобки ] , но имеют дополнительные возможности вроде лучшей поддержки регулярных выражений.
А двойные круглые скобки?
(( Двойные круглые скобки )) это конструкция, позволяющая осуществлять арифметические вычисления внутри Bash. Вам даже не нужно использовать их с if-предложением. Я часто ими пользуюсь, чтобы быстро инкрементировать счетчики и обновлять числовые переменные.
Чего вы не видите, это того, что круглые скобки тоже при каждом запуске возвращают код выхода. Если результат в скобках равен нулю, возвращается код выхода 1 (по сути, нулевой результат это «ложь»). Любой другой результат считается истиной, при нем код выхода будет 0. Вот пример:
К счастью для нас, знаки «больше» и «меньше» внутри круглых скобок работают прекрасно. Если сравнение истинно, результат будет 1. В противном случае – 0.
У этой функциональности есть странный, но любопытный побочный эффект:
Использование команд вместо скобок
Чаще всего в ваших if-предложениях будут использоваться скобки. Однако, поскольку можно использовать команды и их коды выхода, за вашими if-ами будет стоять вся мощь командной строки.
Скажем, мы хотим сделать что-то, но только в том случае, если в файле найдена определенная строка. Какую команду вы будете использовать для поиска текста в файлах? Grep!
Если grep находит искомое, код выхода будет 0 (успех). Если нет, – 1. Мы используем это для запуска нашего if-предложения! Опция -q в grep означает —quiet . Она запрещает вывод найденных строк. Если мы ее уберем, то наш вывод будет выглядеть так:
Использование ваших собственных функций
Самое лучшее в этом всем то, что вы можете написать собственные функции! Это поможет вам инкапсулировать вашу логику в нечто с высокоуровневым именем. Благодаря этому ваши скрипты станут более читаемыми, а ваши намерения – более понятными. И если есть что-то, где мы можем для примера использовать эту дополнительную ясность, это «выбрасывающий» скрипт, который Джерри написал в прошлом году и который мы до сих пор используем в сборочном конвейере.
Мне стоит написать отдельный пост о функциях в Bash, потому что они прекрасны и я их обожаю. А сейчас лишь отмечу, что эти функции работают как маленькие отдельные скрипты. Любые переданные им аргументы могут назначаться позиционно с помощью особых переменных $1 , $2 , $3 и т. д. Число аргументов содержится в переменной $# .
Обратите внимание на использование return вместо exit. Смысл тот же самый, за исключением того, что exit «убивает» весь скрипт, а не просто завершает функцию. Данная функция может использоваться вот так:
Видите, как намерение программиста и логика становятся яснее без реализации деталей и написания громоздких регулярных выражений? Функции в Bash это Хорошо.
Фактически, если функция не возвращает (return) значение недвусмысленно, это возвращаемое значение последней команды в функции используется неявно, поэтому функцию можно сократить:
Если регулярное выражение сработает, код возврата двойных квадратных скобок будет нулевым, и таким образом функция возвращает 0. Если нет, и то, и другое возвращает 1. Это отличный способ давать имена регулярным выражениям.
If – это хорошая вещь
Вот и все! Применяйте полученные знания для чистки своих скриптов. Если у вас есть примеры использования if-предложений в Bash, которые могут быть полезны и другим людям, – поделитесь в комментариях!
В этом руководстве мы познакомим вас с основами if оператора Bash и покажем, как его использовать в сценариях оболочки
Принятие решений — одна из самых фундаментальных концепций компьютерного программирования. Как и в любом другом языке программирования, if , if..else , if..elif..else и вложенные if в Bash могут быть использованы для выполнения кода на основе определенного состояния.
Условия Bash if могут иметь разные формы. Самое основное утверждение if принимает следующую форму:
Если TEST-COMMAND оценивается как True , STATEMENTS выполняется. Если TEST-COMMAND возвращается False , ничего не происходит, STATEMENTS игнорируется.
Как правило, рекомендуется всегда делать отступы для вашего кода и отделять блоки кода пустыми строками. Большинство людей предпочитают использовать отступы с 4 или 2 пробелами. Отступы и пустые строки делают ваш код более читабельным и упорядоченным.
Давайте посмотрим на следующий пример сценария, который проверяет, больше ли заданное число, чем 10:
Сохраните код в файле и запустите его из командной строки:
Скрипт предложит вам ввести номер. Например, если вы введете 15, test команда выполнит оценку, true потому что 15 больше 10, и echo команда внутри then условия будет выполнена.
if..else
Оператор Bash if..else принимает следующую форму:
Если TEST-COMMAND оценка до True , STATEMENTS1 будет выполнен. В противном случае, если TEST-COMMAND возвращается False , STATEMENTS2 будет выполнен. Вы можете иметь только одно else условие в объявлении.
Давайте добавим else условие в предыдущий пример сценария:
Если вы запустите код и введете число, сценарий напечатает другое сообщение в зависимости от того, больше это число или меньше / равно 10.
if..elif..else
Оператор Bash if..elif..else принимает следующую форму:
Вы можете иметь одно или несколько elif условий в объявлении. else Пункт не является обязательным.
Условия оцениваются последовательно. Как только условие возвращается, True остальные условия не выполняются, и управление программой переходит к концу if операторов.
Давайте добавим условие elif к предыдущему сценарию:
Вложенные if
Bash позволяет вам вкладывать if утверждения в if утверждения. Вы можете разместить несколько if операторов внутри другого if оператора.
Следующий скрипт предложит вам ввести три числа и напечатает наибольшее число среди трех чисел.
Вот как будет выглядеть вывод:
Как правило, более эффективно использовать case оператор вместо вложенных 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 — True, если FILE существует и является исполняемым.
-d FILE — True, если FILE существует и является каталогом.
-e FILE — Истинно, если FILE существует и является файлом, независимо от типа (узел, каталог, сокет и т. Д.).
-f FILE — True, если FILE существует и является обычным файлом (не каталогом или устройством).
Вывод
Операторы if , if..else and if..elif..else позволяют контролировать поток выполнения скрипта Bash, оценивая заданные условия.