Условные конструкции
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) включен, сопоставление выполняется без учёта регистра букв. Символ '|' используется для разделения нескольких шаблонов, а символ ')' завершает список шаблонов. Список шаблонов и связанный с ним список команд называется 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."
Если используется оператор ';;', после первого совпадения шаблона дальнейшие проверки не выполняются. Использование ';&' вместо ';;' приводит к продолжению выполнения с command-list, связанным со следующим блоком, если таковой имеется. Использование ';;&' вместо ';;' заставляет оболочку проверить шаблоны в следующем блоке, если таковой имеется, и выполнить любой связанный command-list при успешном совпадении, продолжив выполнение оператора case так, как если бы список шаблонов не совпал.
Код возврата равен нулю, если ни один pattern не совпадает. В противном случае код возврата — это код возврата выполненного command-list.
select-
Конструкция
selectпозволяет легко генерировать меню. Она имеет почти такой же синтаксис, как командаfor:select name [in words …]; do commands; done
Список слов, следующих за
in, расширяется, создавая список элементов, и набор расширенных слов печатается в стандартный поток ошибок, каждый предваряется номером. Если 'in words' опущено, печатаются позиционные параметры, как если бы был указан 'in "$@"'.selectзатем отображает приглашениеPS3и считывает строку из стандартного ввода. Если строка содержит число, соответствующее одному из отображенных слов, то значение name устанавливается на это слово. Если строка пуста, слова и приглашение отображаются снова. ЕслиEOFпрочитано, командаselectзавершается и возвращает 1. Любое другое введённое значение приводит к установке значения name в пустую строку. Прочитанная строка сохраняется в переменнойREPLY.Команды commands выполняются после каждого выбора до тех пор, пока не выполняется команда
break, в этот момент командаselectзавершается.Вот пример, который позволяет пользователю выбрать имя файла из текущей директории и отображает имя и индекс выбранного файла.
select fname in *; do echo you picked $fname \($REPLY\) break; done
((…))-
(( expression ))
Арифметическое выражение expression оценивается согласно правилам, описанным ниже (см. Арифметика оболочки). expression подвергается тем же расширениям, как если бы оно находилось в двойных кавычках, но символы двойных кавычек в expression не обрабатываются специально и удаляются. Если значение выражения отлично от нуля, код возврата равен 0; в противном случае код возврата равен 1.
[[…]]
-
[[ expression ]]
Возвращает 0 или 1 в зависимости от результата вычисления условного выражения 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"’ он может соответствовать только буквально ‘.’.
Аналогично, если вы хотите включить символ в свой шаблон, который имеет специальное значение в грамматике регулярных выражений, вы должны убедиться, что он не заключен в кавычки. Например, если вы хотите закрепить шаблон в начале или конце строки, вы не можете заключить символы ‘^’ или ‘$’ в кавычки с использованием какого-либо механизма кавычек оболочки.
Если вы хотите сопоставить ‘начальная строка’ в начале строки, следующее сработает:
[[ $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