Linux if несколько условий

Обновлено: 04.07.2024

В этом руководстве мы познакомим вас с основами оператора 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 в предыдущий пример сценария:

Оператор 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 .

Следующий сценарий предложит вам ввести три числа и напечатает наибольшее число из трех.

Вот как будет выглядеть результат:

Как правило, более эффективно использовать оператор case вместо вложенных операторов if .

Несколько условий

Логические операторы OR и AND позволяют использовать несколько условий в операторах if .

Вот еще одна версия скрипта для печати наибольшего числа из трех. В этой версии вместо вложенных операторов if мы используем логический оператор AND ( && ).

Операторы тестирования

В Bash команда test принимает одну из следующих синтаксических форм:

Чтобы сделать сценарий переносимым, лучше использовать старую команду test [ которая доступна во всех оболочках POSIX. Новая обновленная версия test команды [[ (двойные скобки) поддерживается в большинстве современных систем, использующих Bash, Zsh и Ksh в качестве оболочки по умолчанию.

Чтобы отрицать тестовое выражение, используйте оператор логического NOT ( ! ). При сравнении строк всегда используйте одинарные или двойные кавычки, чтобы избежать проблем с разделением слов и подстановкой слов.

Ниже приведены некоторые из наиболее часто используемых операторов:

Выводы

Операторы if , if..else и if..elif..else позволяют вам управлять потоком выполнения сценария Bash, оценивая заданные условия.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Или нужно обязательно городить такое:


Ничего не понял, но тебе нужно почитать про булеву алгебру, в частности, про законы де Моргана.

Можно и однострочник:

Кстати, bash здесь не при чём:

Deleted ( 06.06.19 20:37:51 )
Последнее исправление: Deleted 06.06.19 20:39:02 (всего исправлений: 1)


это вообще выполнимо одновременно? или в bash всё-таки чуть иначе операторы и/или работают (что я подозреваю)? то есть последовательно выполняются действия?

то есть если [ «$ret» != «0» ] вернёт false, то будет ли выполнено следующее сравнение и, далее, будет ли выполнен последний вывод?

Я проверю, конечно, сейчас не могу. Но мне казалось, что команда после && сработает только если в первой команде возвращается true

grem ★★★★★ ( 06.06.19 20:42:42 )
Последнее исправление: grem 06.06.19 20:45:53 (всего исправлений: 4)



то есть я хочу вернуть FAIL, только если $ret не равно 0 или 2

grem ★★★★★ ( 06.06.19 20:47:06 )
Последнее исправление: grem 06.06.19 20:47:18 (всего исправлений: 1)


работает, а я упорно использовал || что-то меня на ней переклинило :)



В моём случае будет, так как какое-нибудь значение предыдущая перед ret=$? команда вернёт. В крайнем случае, это будет не хуже текущих принятых реализаций в ebuild, где сначала идёт команда, затем || die «message».

Другое дело, что меня переглючило и я операторы pipeline пытался воспринимать как в большинстве языков, хотя в тоже время знал, как они работали - меня чего-то накрыло :)


Не надо увлекаться такими однострочниками. Они не совсем так работают в комлексе, как некоторые тут себе представляют, ибо операции || и && они не свертываются, а выполняются последовательно. Следовательно

vodz ★★★★★ ( 07.06.19 09:57:33 )
Последнее исправление: vodz 07.06.19 09:59:28 (всего исправлений: 1)

Так в данном случае и нужно последовательно. В других случаях, естественно, не стоит так пользовать.



верный вариант. (( )) - для чисел и математических операций [[ ]] - для строк


мне тут такой вариант ещё предложили: [[ $? == [02] ]]

Тока это уже bash, что не всегда годно.


На это намекаешь?


мне и нужна была проверка условий в bash - это для ebuild’а

Да, нормальный скриптовый яп обычно годнее.


верный вариант. (( )) - для чисел и математических операций [[ ]] - для строк

Глупости какие. Если у вас два выражения, одно целочисленное, другое - строковое, то вы всё равно всё заключите в [[ ]], и сразу возникает вопрос, накой (( )) вообще. Нет, я знаю, где (()) удобен, например, в [[ ]] нельзя красиво сделать ((булевое ? целочисленное1 : целочисленное2)). А втыкание (()) внутри [[ ]] зачастую от незнания, что для целочисленных выражений ни $, ни лишние скобки нафиг не нужны. Сравните:

с реализацией через (()) - насколько пример красивее и нагляднее без кучи скобок. vodz ★★★★★ ( 09.06.19 12:18:32 )
Последнее исправление: vodz 09.06.19 12:20:20 (всего исправлений: 2)


с данном случае оба операнда числовые.

втыкание (()) внутри [[ ]] зачастую от незнания

где вы увидели (()) внутри [[]]?

насколько пример красивее и нагляднее без кучи скобок.

зависит от ситуации


он про то, что [ и ] - отдельные бинари, а [[ и ]] - функции баша.


с данном случае оба операнда числовые.

А [inline](( EUID == 0 && error != 0 ))[/inline] – сложно, нерасширяемо и неудобно?


Может стоит прочитать, перед тем как отвечать? Это невозможно, для строчного error.

Может стоит прочитать, перед тем как отвечать?

У ОП-а не сторчный error, а числовой.


Может стоит прочитать, перед тем как отвечать? У ОП-а не сторчный error, а числовой.

А у ТСа вообще error-а не было.

vodz ★★★★★ ( 11.06.19 09:46:29 )
Последнее исправление: vodz 11.06.19 09:51:23 (всего исправлений: 3)


А можно ещё и более красиво вот так:


А можно ещё и более красиво вот так:

Ничего тут не красивее, а уж что медленнее, так совершенно очевидно.

Не шибко пользую, из-за ассоциаций с Си. Там только int допустим.

в плане простоты и расширяемости? В плане читаемости первый вариант по-моему лучше, хотя при этом оба плохи.

И попробовать написать на bash что-нибудь сложнее Hello wordl. И сразу станет понятно, что как надо чуть сложнее, чем одномерные массивы, то есть другие комплексные типы, так сразу приходится работать только со строками, наподобие как awk эмулирует внутри себя многомерные массивы (что не совсем в результате идеально), списки и т. д.

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


Вы путаете с $(()), который раньше был как $[].

Тем, что читать надо тред. Тут уже обсуждалось


Это вредная ассоциация, ибо bash свою убогость, справедливости ради, всё же пытается компенсировать, а именно масками в case и в [[]] и даже regex-ами [[ =

]], а ваши ассоциации превращают всё в гвозди для молотка, хотя есть отвертка и шурупы тоже.


Поделил на ноль, поздравляю. ;) Даже, если допустить, что так … who cares? Это баш. Читабельность важнее.


Не шибко пользую, из-за ассоциаций

А зря. Полезная штука. Например для разбора параметров:

beastie ★★★★★ ( 11.06.19 14:59:05 )
Последнее исправление: beastie 11.06.19 14:59:40 (всего исправлений: 1)


Конечно. При коротких условиях городить case — такая читабельность . Вот буквально час назад написал в новой версии jq.sh в новой функции sort:

Похоже? Вроде бы да, но совсем нет, ибо все три и условия и действия — разные. Тут — уместно. vodz ★★★★★ ( 11.06.19 15:01:36 )
Последнее исправление: vodz 11.06.19 15:03:59 (всего исправлений: 2)

Разбор параметров - это отдельная тема. В нём case - само собой разумеющееся. Но в остальных местах уже не пользую.

Насчет POSIX действительно перепутал. Но в bash (()) был на пару лет раньше [[]]. Не то, чтобы это что-то кардинально меняло, просто факт.

Тем, что читать надо тред. Тут уже обсуждалось

Обсуждалось наивное использование конструкций вида A && B || C вместо if A; then B; else C; fi для сокращения кода. Но это не значит, что нужно избегать использования && и || везде (учитывая еще и то, что в условии очень часто может быть не только сравнение чисел или строк, но и команда). Нужно знать и всегда помнить, как они работают. Точно так же, как, например, нужно знать и помнить, что в [[]] есть два разных набора операторов сравнения для целых чисел и строк. В обоих случаях незнание приведет к ошибкам и неправильному пониманию кода.


Не то, чтобы это что-то кардинально меняло, просто факт.

В обоих случаях незнание приведет к ошибкам и неправильному пониманию кода.

Условные операторы if..else командной оболочки Bash

Принятие решений - одна из самых фундаментальных концепций компьютерного программирования. Как и в любом другом языке программирования, if , if..else , if..elif..else и вложенные if в Bash могут быть использованы для выполнения кода на основе определенного состояния.

Условия Bash if могут иметь разные формы. Самое основное утверждение if принимает следующую форму:

Объявление начинается с ключевым словом if , за которым следует условному выражение и then ключевым словом. Утверждение заканчивается ключевым словом fi .

Если 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 условие в предыдущий пример сценария:

if..elif..else

Оператор Bash if..elif..else принимает следующую форму:

Если TEST-COMMAND1 оценка до True , STATEMENTS1 будет выполнен. Если TEST-COMMAND2 оценка до True , STATEMENTS2 будет выполнен. Если ни одна из тестовых команд не оценивается True , STATEMENTS2 выполняется.

Вы можете иметь одно или несколько 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, оценивая заданные условия.

Условия в скриптах bash (условные операторы)

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

Условие в этом примере по сути является командой. Это может звучать странно, но сравнение с квадратными скобками аналогично использованию встроенной команды test , например:

Если $foo больше(G) или равно(E) 3, блок после «then» будет выполнен. Если вы всегда задавались вопросом, почему bash использует -ge или -eq вместо >= или ==, это потому, что этот тип условия исходит из команды, где -ge и -eq - параметры. И это то, что по сути, проверяет состояние завершения команды. Я объясню это более подробно далее в руководстве. Также есть встроенные проверки, которые более специфичны для оболочек.

Вышеуказанное условие выполняется, если файл «regularfile» существует и это обычный файл. Обычный файл означает, что это не блок или символьное устройство или каталог. Таким образом, вы можете быть уверены, что Файл существует, прежде чем что-то делать с ним. Вы даже можете проверить, если файл читабелен!

Приведенное выше условие выполняется, если файл «readablefile» существует и доступен для чтения. Легко, не правда ли?

Синтаксис оператора if (краткое объяснение)

Основной синтаксис оператора if … then выглядит следующим образом:

Условие, в зависимости от его типа, окружено определенным скобки, например. []. Вы можете прочитать о различных типах дальше в учебнике. Вы можете добавить команды, которые будут выполняться, когда условие ложно, с помощью ключевого слова else и использовать ключевое слово elif (elseif) для выполнения команд с другим условием, если основное условие ложно. Ключевое слово else всегда стоит последним. Пример:

Краткое объяснение примера: сначала мы проверяем, является ли файл somefile читаемым («if [-r somefile ]»). Если так, мы читаем это в переменную. Если нет, мы проверяем, существует ли он на самом деле («elif [-f somefile ]»). Если это правда, мы сообщаем, что он существует, но не читается (если бы это было так, мы бы прочитали содержимое). Если файл не существует, мы также сообщаем об этом. Условие в elif выполняется только в том случае, если условие в if было ложным. Команды, принадлежащие else, выполняются, только если оба условия ложны.

Основные правила условий

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

Всегда оставляйте пробелы между скобками и фактической проверкой/сравнением. Следующие не будут работать:

Баш будет жаловаться на “отсутствуoщий ']'”.

Всегда заканчивайте строку перед введением нового ключевого слова, такого как «then». Слова if, then, else, elif и fi являются ключевыми словами оболочки, что означает, что они не могут использовать одну и ту же строку. Поместите «;» между предыдущим оператором и ключевым словом или поместите ключевое слово в начале новой строки. Bash будет выдавать ошибки, такие как «ошибка синтаксиса, рядом с неожиданным токеном «fi», если вы этого не сделаете.

Это хорошая привычка заключать в кавычки строковые переменные, если вы используете их в условиях, потому что в противном случае они могут создать проблемы, если они содержат пробелы и/или символы новой строки. Цитируя я имею в виду:

Есть несколько случаев, в которых вы не должны экранировать ковычками, но они редки. Вы увидите одну из них далее в руководстве.

Кроме того, есть две вещи, которые может быть полезно знать:

Вы можете инвертировать условие, поставив перед ним «!». Пример:

Обязательно поместите "!" В скобки!

Вы можете комбинировать условия с помощью определенных операторов. Для синтаксиса с одной скобкой, который мы использовали до сих пор, вы можете использовать «-a» для and и «-o» для or. Пример:

Приведенное выше условие вернет true, если $foo содержит целое число, большее или равное 3 и меньшее (Less Than) 10. Подробнее об этих выражениях объединения можно прочитать в соответствующих синтаксисах условий.

И еще одна базовая вещь: не забывайте, что условия могут также использоваться в других операторах, таких как while и until. Объяснение этого не входит в этот урок, но вы можете прочитать о них в Руководстве по Bash для начинающих.

Во всяком случае, я пока показал вам только условия в одинарных скобках. Однако есть и другие синтаксисы, о которых вы узнаете в следующем разделе.

Различные синтаксисы условий

Bash имеет различные синтаксисы для условий. Я перечислю три из них:

1. Синтаксис с одной скобкой

Это синтаксис условия, который вы уже видели в предыдущих параграфах; это самый старый поддерживаемый синтаксис. Он поддерживает три типа условий:

Файловые условия

Позволяет различные виды проверок. Пример:

Приведенное выше условие верно, если файл символическая ссылка существует и является символической ссылкой. Дополнительные условия для файлов см. в таблице ниже.

Строковые условия

Позволяет проверять строку и сравнивать строки. Пример первый:

Вышеуказанное условие истинно, если $emptystring является пустой строкой или неинициализированной переменной. Пример два:

Приведенное выше условие истинно, если $stringvar1 содержит только строку «cheese». Дополнительные условия на основе строк см. в таблице ниже.

Арифметические (числовые) условия

Позволяет сравнивать целые числа. Пример:

Приведенное выше условие возвращает true, если $num меньше 1. Более подробные арифметические условия см. в таблице ниже.

2. Синтаксис в двойных скобках

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

Синтаксис двойной скобки служит расширенной версией синтаксиса одной скобки; он в основном имеет те же особенности, но и некоторые важные различия с ним. Я перечислю их здесь:

Первое отличие_ можно увидеть в приведенном выше примере; при сравнении строк в синтаксисе двойных скобок используется глобализация оболочки(shell globbing). Это означает, что звездочка («*») расширится буквально до чего угодно, как вы, вероятно, знаете из обычного использования командной строки. Поэтому, если $stringvar где-либо содержит фразу «string», условие вернет true. Допускаются и другие формы срыва оболочки. Если вы хотите сопоставить и строку «String», и строку «string», вы можете использовать следующий синтаксис:

Обратите внимание, что допускается только общее глобирование оболочки. Такие Bash-специфичные вещи, такие как или , не будут работать. Также обратите внимание, что глобирование не будет работать, если вы экранировали кавычками правую строку. В этом случае вы должны оставить его без кавычек.

Второе отличие - это то, что разделение слов предотвращено. Следовательно, вы можете опустить размещение кавычек вокруг строковых переменных и без проблем использовать условие, подобное следующему:

Тем не менее, цитирование строковых переменных остается хорошей привычкой, поэтому я рекомендую просто продолжать это делать.

Третье отличие состоит в том, что имена файлов не расширяются. Я проиллюстрирую это различие на двух примерах, начиная со старой ситуации с одной скобкой:

Вышеуказанное условие вернет true, если в рабочем каталоге есть один файл с расширением .sh. Если их нет, он вернет false. Если есть несколько файлов .sh, bash выдаст ошибку и прекратит выполнение скрипта. Это связано с тем, что *.sh распространяется на файлы в рабочем каталоге. Использование двойных скобок предотвращает это:

Приведенное выше условие вернет true, только если в рабочем каталоге есть файл с именем «*.sh», независимо от того, какие существуют другие файлы .sh. Звездочка взята буквально, потому что синтаксис в двойных скобках не расширяет имена файлов.

Четвертое отличие - это добавление более общеизвестных объединяющих выражений или, более конкретно, операторов «&&» и «||». Пример:

Приведенное выше условие возвращает true, если $num равно 3, а $stringvar равно «foo». Также поддерживаются -a и -o, известные из синтаксиса с одной скобкой.

Обратите внимание, что оператор and имеет приоритет над оператором or, что означает, что «&&» или «-a» будет оцениваться перед «||» или «-о».

Пятое отличие состоит в том, что синтаксис в двойных скобках позволяет сопоставлять шаблоны с помощью оператора «=

». Смотрите таблица для получения дополнительной информации.

3. Синтаксис с двойными скобками

Существует также другой синтаксис для арифметических (основанных на числах) условий, наиболее вероятно взятый из оболочки Korn:

Приведенное выше условие выполняется, если $num меньше или равно 5. Этот синтаксис может показаться программистам более знакомым. Он включает в себя все "нормальные" операторы, такие как ==, <-> и =>. Он поддерживает комбинирующие выражения «&&» и «||» (но не выражения -a и -o!). Это эквивалентно встроенной команде let.

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

1. File-based conditions:

/.kde ]; then
echo “You seem to be a kde user.”
fi

if [ -g . ]; then
echo “Created files are inheriting the group ‘$(ls -ld . | awk ‘< print $4 >’)’ from the working directory.”
fi

if [ -u executable ]; then
echo “Running program executable as user $(ls -l executable | awk ‘< print $3 >’).”
fi

if [ -x /root ]; then
echo “You can view the contents of the /root directory.”
fi

2. String-based conditions:

(Don’t feel ashamed if you don’t understand this, it is a more complex example)

array=( linux tutorial blog )
swaps=1
while (( swaps > 0 )); do

Note that you can also omit the “-n”, as brackets with just a string in it behave the same.

“b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]b” ]]; then
echo “$email contains a valid e-mail address.”
fi

3. Arithmetic (number-based) conditions:

if [ $(ps -p $pid -o ni=) -ne $(nice) ]; then
echo “Process $pid is running with a non-default nice value”
fi

if [ $num -lt 0 ]; then
echo “Negative numbers not allowed; exiting…”
exit 1
fi

4. Miscellaneous conditions:

С помощью синтаксиса с двойными круглыми скобками вы можете использовать следующие условия:

5. Double-parenthesis syntax conditions:

if (( $(ps -p $pid -o ni=) != $(nice) )); then
echo “Process $pid is running with a non-default nice value”
fi

if (( $num < 0 )); then
echo “Negative numbers not allowed; exiting…”
exit 1
fi

После этой сухой информационной нагрузки, здесь есть небольшое объяснение для тех, кто хочет узнать больше .

Погружение немного глубже

Я сказал, что расскажу больше о том, что if по существу проверяет состояние завершения команд. И я так и сделаю. Основное правило bash, когда дело доходит до условий: 0 равно true, >0 равно false. Это в значительной степени противоположно многим языкам программирования, где 0 равно false, а 1 (или более) равно true. Причиной этого является то, что оболочки типа bash часто работают с программами. По соглашению UNIX программы используют состояние выхода для указания того, что выполнение прошло нормально или произошла ошибка. Поскольку успешное выполнение не требует каких-либо объяснений, ему нужен только один статус выхода. Однако, если возникла проблема, полезно знать, что пошло не так. Следовательно, 0 используется для успешного выполнения, а 1-255 для указания, какая ошибка произошла. Значения чисел 1-255 различаются в зависимости от программы, возвращающей их.

В любом случае, if выполняет блок после then, когда команда возвращает 0. Да, условия являются командами. Фраза [$ foo -ge 3 ] возвращает статус завершения, а также два других синтаксиса! Следовательно, есть удобный прием, который вы можете использовать для быстрого тестирования состояния:

В этом примере «echo true» выполняется только в том случае, если [$ foo -ge 3 ] возвращает 0 (true). Почему это так, спросите вы? Это потому, что bash оценивает состояние только при необходимости. При использовании комбинирующего выражения and оба условия должны быть истинными, чтобы комбинированное выражение возвращало true. Если первое условие возвращает false, не имеет значения, что возвращает второе; результат будет ложным. Следовательно, bash не оценивает второе условие, и именно поэтому в этом примере «echo true» не выполняется. То же самое относится к оператору or («||»), где второе условие не оценивается, если первое условие истинно.

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

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

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

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

-z – строка пуста

-n – строка не пуста

=, ( == ) – строки равны

!= – строки неравны

-eq – равно

-ne – неравно

-lt,(< ) – меньше

-le,(<=) – меньше или равно

-gt,(>) – больше

-ge,(>=) - больше или равно

! - отрицание логического выражения

-a,(&&) – логическое «И»

-o,(||) -логическое «ИЛИ»

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

Другими словами:

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

Пример 1

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

Пример 2

Пример 3

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

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

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

Пример 4

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

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

Пример 5

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

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

Пример 6

Ключи к файлам и каталогам

[ -ключ “путь” ]
[ -e “путь каталогу_или_файлу”] – существует ли файл или каталог.

[ -r “путь к файлу/каталогу”] – доступен ли файл/каталог для чтения.

[ -f “путь к файлу/каталогу”] – существует ли файл.

[ -d “путь к каталогу”] – существует ли каталог.
Полное описание возможных применений различных скобок, правильное расставление кавычек уходит далеко от темы, поэтому могу посоветовать обратится к руководству Advanced Bash Scripting

Арифметика

Пример 7

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

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

Пример 8

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

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

Пример 9

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

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

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

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

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

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

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

Читайте также: