Как использовать условные тесты с двойными скобками в Linux
Опубликовано: 2022-01-29Условные тесты разветвляют поток выполнения скриптов Linux Bash в соответствии с результатом логического выражения. Условные тесты с двойными скобками значительно упрощают синтаксис, но все же имеют свои недостатки.
Одиночные и двойные кронштейны
Bash предоставляет test
команду. Это позволяет тестировать логические выражения. Выражение вернет ответ, указывающий на истинный или ложный ответ. Истинный ответ обозначается возвращаемым значением, равным нулю. Все, кроме нуля, указывает на ложь.
Эта функция используется для объединения команд в командной строке с оператором &&
. Команды выполняются только в том случае, если предыдущая команда завершилась успешно.
Если проверка верна, будет напечатано слово «Да».
тест 15 -eq 15 && эхо "Да"
тест 14 -eq 15 && эхо "Да"
Условные тесты с одной скобкой имитируют команду test
. Они заключают выражение в скобки « [ ]
» и работают так же, как команда test
. По сути, это одна и та же программа, созданная из одного и того же исходного кода. Единственная операционная разница заключается в том, как test
версия и [
версия обрабатывают запросы на помощь.
Это из исходного кода:
/* Распознать --help или --version, но только при вызове в Форма "[", когда последний аргумент не "]". Используйте прямой синтаксический анализ, а не parse_long_options, чтобы избежать принятия сокращения. POSIX позволяет "[ --help" и "[ --version" имеет обычное поведение GNU, но требует "test --help" и "test --version" для автоматического выхода со статусом 0. */
Мы можем увидеть эффект этого, обратившись к test
и [
за помощью и проверив код ответа, отправленный в Bash.
тест --помощь
эхо $?
[ --помощь
эхо $?
И test
и [
являются встроенными оболочками, что означает, что они встроены прямо в Bash. Но есть также отдельная бинарная версия [
.
типовой тест
тип [
где [
Напротив, условные проверки с двойными скобками [[
и ]]
являются ключевыми словами . [[
и ]]
также выполняют логические проверки, но их синтаксис отличается. Поскольку это ключевые слова, вы можете использовать некоторые полезные функции, которые не будут работать в версии с одной скобкой.
Ключевые слова с двойными скобками поддерживаются Bash, но они недоступны в любой другой оболочке. Например, оболочка Korn их поддерживает, а старая добрая оболочка sh — нет. Все наши скрипты начинаются со строки:
#!/бин/баш
Это гарантирует, что мы вызываем оболочку Bash для запуска скрипта.
СВЯЗАННЫЕ С: Как создавать и запускать сценарии оболочки Bash в Windows 10
Встроенные функции и ключевые слова
Мы можем использовать программу compgen
для вывода списка встроенных функций:
компген -б | фмт -w 70
Без передачи вывода через fmt
мы получили бы длинный список с каждой встроенной функцией в отдельной строке. В этом случае удобнее видеть встроенные модули, сгруппированные в абзац.
Мы можем видеть test
и [
в списке, но ]
нет в списке. Команда [
ищет закрытие ]
для определения достижения конца выражения, но ]
не является отдельной встроенной функцией. Это просто сигнал, который мы даем [
, чтобы указать конец списка параметров.
Чтобы увидеть ключевые слова, мы можем использовать:
компген -k | фмт -w 70
Ключевые слова [[
и ]]
находятся в списке, потому что [[
— это одно ключевое слово, а ]]
— другое. Они представляют собой согласованную пару, как if
и fi
, case
и esac
.
Когда Bash анализирует сценарий или командную строку и обнаруживает ключевое слово, имеющее совпадающее закрывающее ключевое слово, он собирает все, что появляется между ними, и применяет любую специальную обработку, которую поддерживают ключевые слова.
Со встроенной командой то, что следует за встроенной командой, передается ей точно так же, как параметры любой другой программе командной строки. Это означает, что автор сценария должен проявлять особую осторожность в отношении таких вещей, как пробелы в значениях переменных.
Подстановка оболочки
Условные тесты с двойными скобками могут использовать подстановку оболочки. Это означает, что звездочка « *
» расширится и будет означать «что угодно».
Введите или скопируйте следующий текст в редактор и сохраните его в файле с именем «whelkie.sh».
#!/бин/баш stringvar="Уэлки Брукс" если [[ "$stringvar" == *elk* ]]; тогда echo "Предупреждение содержит морепродукты" еще echo "Без моллюсков" фи
Чтобы сделать скрипт исполняемым, нам нужно использовать команду chmod
с параметром -x
(выполнить). Вам нужно будет сделать это со всеми сценариями в этой статье, если вы хотите попробовать их.
chmod +x whelkie.sh
Когда мы запускаем скрипт, мы видим, что строка «elk» была найдена в строке «Whelkie», независимо от того, какие другие символы ее окружают.
./whelkie.sh
Следует отметить, что мы не заключаем строку поиска в двойные кавычки. Если вы это сделаете, подстановка не произойдет. Строка поиска будет обработана буквально.
Допускаются другие формы глобирования оболочки. Знак вопроса « ?
” будет соответствовать одиночным символам, а одинарные квадратные скобки используются для обозначения диапазонов символов. Например, если вы не знаете, какой регистр использовать, вы можете охватить оба варианта диапазоном.
#!/бин/баш stringvar="Жан-Клод ван Клам" если [[ "$stringvar" == *[cC]lam* ]]; тогда echo "Предупреждение содержит морепродукты." еще echo "Без моллюсков." фи
Сохраните этот скрипт как «damme.sh» и сделайте его исполняемым. Когда мы запускаем его, условный оператор принимает значение true, и выполняется первое предложение оператора if.
./damme.sh
Цитаты строк
Ранее мы упоминали о заключении строк в двойные кавычки. Если вы это сделаете, подстановка оболочки не произойдет. Хотя соглашение гласит, что это хорошая практика, вам не нужно заключать строковые переменные в кавычки при использовании [[
и ]]
, даже если они содержат пробелы. Посмотрите на следующий пример. Обе строковые переменные $stringvar
и $surname
содержат пробелы, но ни одна из них не заключена в кавычки в условном выражении.
#!/бин/баш stringvar="Ван Дамм" фамилия = "Ван Дамм" если [[ $stringvar == $surname ]]; тогда echo "Фамилии совпадают." еще echo "Фамилии не совпадают." фи
Сохраните это в файл с именем «surname.sh» и сделайте его исполняемым. Запустите его, используя:
./фамилия.ш
Несмотря на то, что обе строки содержат пробелы, сценарий выполняется успешно, и условное выражение принимает значение true. Это полезно при работе с путями и именами каталогов, которые содержат пробелы. Здесь параметр -d
возвращает значение true, если переменная содержит допустимое имя каталога.
#!/бин/баш dir="/home/dave/Документы/Нужна работа" если [[ -d ${каталог} ]]; тогда echo "Каталог подтвержден" еще эхо "Каталог не найден" фи
Если вы измените путь в сценарии так, чтобы он отражал каталог на вашем собственном компьютере, сохраните текст в файл с именем «dir.sh» и сделаете его исполняемым, вы увидите, что это работает.
./дир.ш
СВЯЗАННЫЕ С: Как работать с переменными в Bash
Ошибки при объединении имен файлов
Интересное различие между [ ]
и [[ ]]
относится к именам файлов с подстановкой в них. Форма «*.sh» будет соответствовать всем файлам скриптов. Использование одиночных квадратных скобок [ ]
не работает, если нет одного файла сценария. При обнаружении более одного скрипта выдается ошибка.
Вот скрипт с условными обозначениями в одной скобке.
#!/бин/баш если [-a *.sh]; тогда echo "Найден файл скрипта" еще echo "Не найден файл скрипта" фи
Мы сохранили этот текст в «script.sh» и сделали его исполняемым. Мы проверили, сколько скриптов было в каталоге, а затем запустили скрипт.
лс
./script.sh
Баш выдает ошибку. Мы удалили все файлы сценария, кроме одного, и снова запустили сценарий.
лс
./script.sh
Условная проверка возвращает true, и сценарий не вызывает ошибки. Редактирование сценария для использования двойных скобок обеспечивает третий тип поведения.
#!/бин/баш если [[ -a *.sh ]]; тогда echo "Найден файл скрипта" еще echo "Не найден файл скрипта" фи
Мы сохранили это в файл с именем «dscript.sh» и сделали его исполняемым. Запуск этого скрипта в каталоге с большим количеством скриптов не приводит к ошибке, но скрипт не может распознать какие-либо файлы скриптов.
Условный оператор, использующий двойные скобки, принимает значение true только в маловероятном случае, когда в каталоге есть файл с именем «*.sh».
./dscript.sh
Логические И и ИЛИ
Двойные скобки позволяют использовать &&
и ||
как логические операторы И и ИЛИ.
Этот скрипт должен преобразовать условное выражение в true, потому что 10 действительно равно 10, а 25 меньше 26.
#!/бин/баш первый=10 секунда=25 если [[ первый -eq 10 && второй -lt 26 ]]; тогда эхо "Условие выполнено" еще эхо "Условие не выполнено" фи
Сохраните этот текст в файл с именем «and.sh», сделайте его исполняемым и запустите с помощью:
./и.ш
Скрипт выполняется так, как мы и ожидали.
На этот раз мы будем использовать ||
оператор. Условный оператор должен разрешиться как истина, потому что, хотя 10 не больше 15, 25 все же меньше 26. Пока либо первое сравнение, либо второе сравнение истинны, условное выражение в целом разрешается как истина.
Сохраните этот текст как «or.sh» и сделайте его исполняемым.
#!/бин/баш первый=10 секунда=25 если [[ первый -gt 15 || второй -lt 26 ]]; тогда эхо "Условие выполнено." еще echo "Условие не выполнено." фи
./или.ш
Регулярные выражения
Условные операторы с двойными скобками позволяют использовать оператор =~
, который применяет шаблоны поиска регулярных выражений в строке к другой половине оператора. Если регулярное выражение выполняется, условное утверждение считается истинным. Если регулярное выражение не находит совпадений, условное выражение принимает значение false.
СВЯЗАННЫЕ С: Как использовать регулярные выражения (регулярные выражения) в Linux
Сохраните этот текст в файл с именем «regex.sh» и сделайте его исполняемым.
#!/бин/баш слова = "один два три" WordsandNumbers="один 1 два 2 три 3" email="[email protected]" маска1="[0-9]" mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}" если [[ $words =~ $mask1 ]]; тогда echo "\"$words\" содержит цифры." еще echo "В \"$words\" не найдено цифр." фи если [[ $WordsandNumbers =~ $mask1 ]]; тогда echo "\"$WordsandNumbers\" содержит цифры." еще echo "В \"$WordsandNumbers\" не найдено цифр." фи если [[ $email =~ $mask2 ]]; тогда echo "\"$email\" является действительным адресом электронной почты." еще echo "Не удалось разобрать \"$email\"." фи
Первый набор двойных скобок использует строковую переменную $mask1
в качестве регулярного выражения. Он содержит шаблон для всех цифр в диапазоне от нуля до девяти. Это регулярное выражение применяется к строковой переменной $words
.
Второй набор двойных скобок снова использует строковую переменную $mask1
в качестве регулярного выражения, но на этот раз она использует ее со строковой переменной $WordsandNumbers
.
Последний набор двойных скобок использует более сложную маску регулярного выражения в строковой переменной $mask2
.
- [A-Za-z0-9._%+-]+ : соответствует любому символу, который является прописной или строчной буквой, или любой цифрой от нуля до девяти, или точкой, подчеркиванием, знаком процента или знаком плюс или минус. . Знак «
+
» вне «[]
» означает повторение этих совпадений для всех найденных символов. - @ : соответствует только символу «@».
- [A-Za-z0-9.-]+ : соответствует любому символу, который является прописной или строчной буквой, любой цифре от нуля до девяти, точке или дефису. Знак «
+
» вне «[ ]
» означает повторение этих совпадений для всех найденных символов. - . : соответствует «.» только характер.
- [A-Za-z]{2,4} : соответствует любой прописной или строчной букве. «
{2,4}
» означает совпадение не менее двух символов и не более четырех.
Собрав все это вместе, маска регулярного выражения проверит, правильно ли сформирован адрес электронной почты.
Сохраните текст сценария в файл с именем «regex.sh» и сделайте его исполняемым. Когда мы запускаем скрипт, мы получаем этот вывод.
./regex.sh
Первый условный оператор терпит неудачу, потому что регулярное выражение ищет цифры, но в значении, хранящемся в строковой переменной $words
, нет цифр.
Второй условный оператор выполнен успешно, поскольку строковая переменная $WordsandNumbers
действительно содержит цифры.
Окончательный условный оператор завершается успешно, т. е. принимает значение true, поскольку адрес электронной почты имеет правильный формат.
Всего одно условие
Условные тесты с двойными скобками обеспечивают гибкость и удобочитаемость ваших сценариев. Просто возможность использовать регулярные выражения в ваших условных тестах оправдывает изучение того, как использовать [[
и ]]
.
Просто убедитесь, что скрипт вызывает оболочку, которая их поддерживает, например Bash.
СВЯЗАННЫЕ С: 15 специальных символов, которые вам нужно знать для Bash