Условные конструкции
-
if -
Синтаксис команды
if:if test-commands; then consequent-commands; [elif more-test-commands; then more-consequents;] [else alternate-consequents;] fi
Список test-commands выполняется, и если его код возврата равен нулю, выполняется список consequent-commands. Если test-commands возвращает ненулевой код, по очереди выполняется каждый список
elif, и если его код завершения равен нулю, выполняется соответствующий список more-consequents, после чего команда завершается. Если указано ‘else alternate-consequents’ и последняя команда в последнем предложенииifилиelifимеет ненулевой код завершения, выполняется alternate-consequents. Код возврата совпадает с кодом завершения последней выполненной команды или равен нулю, если ни одно условие не оказалось истинным. -
case -
Синтаксис команды
case:case word in [ [(] pattern [| pattern]...) command-list ;;]... esaccaseвыборочно выполняет command-list, соответствующий первому шаблону pattern, которому соответствует word, проверяя шаблоны по порядку, от первого до последнего. Сопоставление выполняется согласно правилам, описанным ниже в разделе Сопоставление с шаблоном. Если включён параметр оболочкиnocasematch(см. описаниеshoptв разделе Встроенная команда shopt), сопоставление выполняется без учёта регистра букв. Символ ‘|’ используется для разделения нескольких шаблонов в списке шаблонов, а оператор ‘)’ завершает список шаблонов. Список шаблонов и связанный с ним command-list называются clause.Каждое предложение должно завершаться символами ‘;;’, ‘;&’ или ‘;;&’. Перед тем как оболочка попытается сопоставить шаблон, к word применяются раскрытие тильды, раскрытие параметров, подстановка команд, подстановка процессов, арифметическое раскрытие и удаление кавычек (см. Раскрытие параметров оболочки). К каждому pattern применяются раскрытие тильды, раскрытие параметров, подстановка команд, арифметическое раскрытие, подстановка процессов и удаление кавычек.
Число предложений
caseможет быть произвольным; каждое завершается символами ‘;;’, ‘;&’ или ‘;;&’. Первый совпавший шаблон определяет список команд, который будет выполнен. Часто в качестве последнего шаблона используют ‘*’, задавая тем самым вариант по умолчанию, поскольку этот шаблон совпадает всегда.Ниже приведён пример использования
caseв скрипте, который можно использовать для описания одной интересной особенности животного:echo -n "Enter the name of an animal: " read ANIMAL echo -n "The $ANIMAL has " case $ANIMAL in horse | dog | cat) echo -n "four";; man | kangaroo ) echo -n "two";; *) echo -n "an unknown number of";; esac echo " legs."
Если используется оператор ‘;;’, выполнение команды
caseзавершается после первого совпадения с шаблоном. Использование ‘;&’ вместо ‘;;’ приводит к тому, что выполнение продолжается со списком command-list, связанным со следующим предложением, если оно есть. Использование ‘;;&’ вместо ‘;;’ приводит к тому, что оболочка проверяет шаблоны в следующем предложении, если оно есть, и выполняет связанный список command-list, если найдено совпадение; выполнение оператора case продолжается так, как если бы список шаблонов не совпал.Код возврата равен нулю, если ни один pattern не совпал. В противном случае код возврата совпадает с кодом завершения последнего выполненного списка command-list.
-
select -
Конструкция
selectпозволяет легко создавать меню. Её синтаксис почти совпадает с синтаксисом командыfor:select name [in words ...]; do commands; done
Сначала раскрывается список слов после
in, формируя перечень элементов, после чего набор раскрытых слов выводится в стандартный поток ошибок, каждое слово предваряется номером. Если ‘in words’ опущено, выводятся позиционные параметры, как если бы было указано ‘in "$@"’. Затемselectвыводит приглашениеPS3и считывает строку из стандартного ввода. Если строка состоит из числа, соответствующего одному из выведенных слов,selectприсваивает переменной name это слово. Если строка пуста,selectснова выводит слова и приглашение. Если считаноEOF, выполнениеselectзавершается с кодом возврата 1. При любом другом введённом значении переменной name присваивается значение null. Считанная строка сохраняется в переменнойREPLY.commands выполняются после каждого выбора, пока не будет выполнена команда
break; после этого выполнение командыselectзавершается.Ниже приведён пример, позволяющий пользователю выбрать имя файла из текущего каталога и выводящий имя и индекс выбранного файла.
select fname in *; do echo you picked $fname \($REPLY\) break; done
((…))-
(( expression ))
Арифметическое expression вычисляется согласно правилам, описанным ниже (см. Арифметика оболочки). К expression применяются те же преобразования, что и в случае, если бы оно находилось в двойных кавычках, однако неэкранированные символы двойной кавычки в expression не обрабатываются особым образом и удаляются. Поскольку в результате могут получиться пустые строки, эта команда рассматривает их как выражения, значение которых равно 0. Если значение выражения отлично от нуля, код возврата равен 0; в противном случае код возврата равен 1.
-
[[…]] -
[[ expression ]]
Вычисляет условное выражение expression и возвращает нулевой статус (истина) или ненулевой (ложь). Выражения состоят из примитивов, описанных ниже в разделе Условные выражения Bash. Слова между
[[и]]не подвергаются разбиению на слова и подстановке имён файлов. Для этих слов оболочка выполняет раскрытие тильды, раскрытие параметров и переменных, арифметическое раскрытие, подстановку команд, подстановку процессов и удаление кавычек. Условные операторы, такие как ‘-f’, должны быть без кавычек, чтобы распознаваться как примитивы.При использовании с
[[операторы ‘<’ и ‘>’ выполняют лексикографическую сортировку с учётом текущей локали.При использовании операторов ‘==’ и ‘!=’ строка справа от оператора рассматривается как шаблон и сопоставляется согласно правилам, описанным ниже в разделе Сопоставление с шаблоном, как если бы был включён параметр оболочки
extglob. Оператор ‘=’ идентичен оператору ‘==’. Если включён параметр оболочкиnocasematch(см. описаниеshoptв разделе Встроенная команда shopt), сопоставление выполняется без учёта регистра букв. Возвращаемое значение равно 0, если строка соответствует (‘==’) шаблону или не соответствует ему (‘!=’), и 1 в противном случае.Если заключить любую часть шаблона в кавычки с помощью любого из способов цитирования оболочки, эта часть будет сопоставляться буквально. Это означает, что каждый символ в заключённой в кавычки части соответствует самому себе, а не имеет какого-либо специального значения для сопоставления с шаблоном.
Доступен дополнительный бинарный оператор ‘=~’ с тем же приоритетом, что и у операторов ‘==’ и ‘!=’. При использовании ‘=~’ строка справа от оператора рассматривается как шаблон расширенного регулярного выражения POSIX и сопоставляется соответствующим образом (с использованием интерфейсов POSIX
regcompиregexec, обычно описываемых в regex(3)). Возвращаемое значение равно 0, если строка соответствует шаблону, и 1, если не соответствует. Если регулярное выражение синтаксически некорректно, условное выражение возвращает 2. Если включён параметр оболочкиnocasematch(см. описаниеshoptв разделе Встроенная команда shopt), сопоставление выполняется без учёта регистра букв.Можно заключить любую часть шаблона в кавычки, чтобы эта часть сопоставлялась буквально, а не как регулярное выражение (см. выше). Если шаблон хранится в переменной оболочки, заключение раскрытия переменной в кавычки заставляет сопоставлять весь шаблон буквально.
Сопоставление успешно, если шаблон соответствует любой части строки. Чтобы заставить шаблон соответствовать всей строке, заякорите его с помощью операторов регулярных выражений ‘^’ и ‘$’.
Например, следующий шаблон соответствует строке (сохранённой в переменной оболочки
line), если где-либо в её значении имеется последовательность символов, состоящая из любого числа (включая ноль) символов класса символовspace, за которыми непосредственно следует ноль или одно вхождение ‘a’, а затем ‘b’:[[ $line =~ [[:space:]]*(a)?b ]]
Это означает, что будут соответствовать такие значения
line, как ‘aab’, ‘ aaaaaab’, ‘xaby’ и ‘ ab’, а также любая строка, содержащая ‘b’ где-либо в своём значении.Чтобы сопоставить символ, имеющий специальное значение в грамматике регулярных выражений (‘^$|[]()\.*+?’), его необходимо заключить в кавычки, чтобы убрать это специальное значение. Это означает, что в шаблоне ‘xxx.txt’ символ ‘.’ соответствует любому символу в строке (как обычно в регулярных выражениях), а в шаблоне ‘"xxx.txt"’ он может соответствовать только буквальному символу ‘.’.
Аналогично, если нужно включить в шаблон символ, имеющий специальное значение в грамматике регулярных выражений, необходимо убедиться, что он не заключён в кавычки. Например, если шаблон требуется заякорить в начале или конце строки, символы ‘^’ и ‘$’ нельзя заключать в кавычки ни одним из способов цитирования оболочки.
Чтобы сопоставить ‘initial string’ в начале строки, подойдёт следующий вариант:
[[ $line =~ ^"initial string" ]]
а этот вариант не подойдёт:
[[ $line =~ "^initial string" ]]
поскольку во втором примере символ ‘^’ заключён в кавычки и не имеет своего обычного специального значения.
Иногда бывает трудно задать регулярное выражение правильно, не используя кавычки, или отслеживать цитирование, используемое регулярными выражениями, одновременно учитывая цитирование оболочки и удаление кавычек оболочкой. Часто удобно сохранять регулярное выражение в переменной оболочки — это помогает избежать проблем с цитированием символов, имеющих специальное значение для оболочки. Например, следующий вариант эквивалентен шаблону, использованному выше:
pattern='[[:space:]]*(a)?b' [[ $line =~ $pattern ]]
Программистам оболочки следует уделять особое внимание обратным косым чертам, поскольку они используются и оболочкой, и регулярными выражениями для снятия специального значения со следующего символа. Это означает, что после завершения раскрытия слов оболочкой (см. Раскрытия оболочки) любые оставшиеся обратные косые черты в изначально не заключённых в кавычки частях шаблона могут снимать специальное значение с символов шаблона. Если какая-либо часть шаблона заключена в кавычки, оболочка старается обеспечить буквальную обработку парсером регулярных выражений оставшихся обратных косых черт, если они находятся в заключённой в кавычки части.
Следующие два набора команд не эквивалентны:
pattern='\.' [[ . =~ $pattern ]] [[ . =~ \. ]] [[ . =~ "$pattern" ]] [[ . =~ '\.' ]]
Первые два сопоставления будут успешными, а вторые два — нет, поскольку во вторых двух примерах обратная косая черта будет частью сопоставляемого шаблона. В первых двух примерах парсеру регулярных выражений передаётся шаблон ‘\.’. Обратная косая черта снимает специальное значение с символа ‘.’, поэтому происходит сопоставление с буквальным символом ‘.’. Во вторых двух примерах парсеру регулярных выражений передаётся шаблон, в котором обратная косая черта заключена в кавычки (например, ‘\\\.’); он не будет соответствовать строке, поскольку та не содержит обратной косой черты. Если бы строка в первых примерах содержала что-либо, кроме ‘.’, например ‘a’, шаблон не совпал бы, поскольку заключённый в кавычки символ ‘.’ в шаблоне теряет своё специальное значение, позволяющее ему соответствовать любому одиночному символу.
Выражения в квадратных скобках в регулярных выражениях также могут быть источником ошибок, поскольку символы, обычно имеющие специальное значение в регулярных выражениях, теряют его внутри квадратных скобок. Однако выражения в квадратных скобках можно использовать для сопоставления со специальными символами шаблона без заключения их в кавычки, поэтому иногда это бывает полезно.
Хотя такая запись может показаться необычной, следующий шаблон будет соответствовать символу ‘.’ в строке:
[[ . =~ [.] ]]
Оболочка выполняет раскрытие слов до передачи шаблона функциям регулярных выражений, поэтому можно считать, что цитирование оболочки имеет приоритет. Как отмечалось выше, после раскрытия оболочки парсер регулярных выражений интерпретирует все оставшиеся в шаблоне незаключённые в кавычки обратные косые черты согласно собственным правилам. Задача состоит в том, чтобы по возможности не заставлять программистов оболочки цитировать символы дважды, поэтому цитирования оболочки должно быть достаточно для цитирования специальных символов шаблона, когда это необходимо.
Массив
BASH_REMATCHсодержит сведения о том, какие части строки соответствовали шаблону. ЭлементBASH_REMATCHс индексом 0 содержит часть строки, соответствующую всему регулярному выражению. Подстроки, соответствующие подвыражениям в круглых скобках внутри регулярного выражения, сохраняются в остальных индексахBASH_REMATCH. ЭлементBASH_REMATCHс индексом n содержит часть строки, соответствующую n-му подвыражению в круглых скобках.Bash задаёт
BASH_REMATCHв глобальной области видимости; объявление этой переменной как локальной приведёт к непредвиденным результатам.Выражения можно объединять с помощью следующих операторов, перечисленных в порядке убывания приоритета:
( expression )-
Возвращает значение expression. Это можно использовать для изменения обычного приоритета операторов.
! expression-
Истина, если expression ложно.
expression1 && expression2-
Истина, если оба выражения — expression1 и expression2 — истинны.
expression1 || expression2Истина, если истинно хотя бы одно из выражений — expression1 или expression2.
Операторы
&&и||не вычисляют expression2, если значения expression1 достаточно, чтобы определить возвращаемое значение всего условного выражения.
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html