практически любой язык программирования включает в себя условные операторы, предназначенные для проверки условий, чтобы выбрать тот или иной путь развития событий в зависимости от этих условий. В 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 и [ ] , обсуждавшимся выше.
В этом руководстве мы познакомим вас с основами 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, оценивая заданные условия.
Источник
Основы BASH. Часть 1
Введение
break выход из цикла for, while или until continue выполнение следующей итерации цикла for, while или until echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода exit выход из оболочки export отмечает аргументы как переменные для передачи в дочерние процессы в среде hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не искать их при следующем обращении kill посылает сигнал завершения процессу pwd выводит текущий рабочий каталог read читает строку из ввода оболочки и использует ее для присвоения значений указанным переменным.\ return заставляет функцию оболочки выйти с указанным значением shift перемещает позиционные параметры налево test вычисляет условное выражение times выводит имя пользователя и системное время, использованное оболочкой и ее потомками trap указывает команды, которые должны выполняться при получении оболочкой сигнала unset вызывает уничтожение переменных оболочки wait ждет выхода из дочернего процесса и сообщает выходное состояние.
И конечно же кроме встроенных команд мы будем использовать целую кучу внешних, отдельных команд-программ, с которыми мы познакомимся уже в процессе
Что необходимо знать с самого начала
1. Любой bash-скрипт должен начинаться со строки:
#!/bin/bash в этой строке после #! указывается путь к bash-интерпретатору, поэтому если он у вас установлен в другом месте(где, вы можете узнать набрав whereis bash) поменяйте её на ваш путь. 2. Коментарии начинаются с символа # (кроме первой строки). 3. В bash переменные не имеют типа(о них речь пойдет ниже)
Переменные и параметры скрипта
Приведу как пример небольшой пример, который мы разберем:
#!/bin/bash #указываем где у нас хранится bash-интерпретатор parametr1=$1 #присваиваем переменной parametr1 значение первого параметра скрипта script_name=$0 #присваиваем переменной script_name значение имени скрипта echo «Вы запустили скрипт с именем $script_name и параметром $parametr1» # команда echo выводит определенную строку, обращение к переменным осуществляется через $имя_переменной. echo ‘Вы запустили скрипт с именем $script_name и параметром $parametr1’ # здесь мы видим другие кавычки, разница в том, что в одинарных кавычках не происходит подстановки переменных. exit 0 #Выход с кодом 0 (удачное завершение работы скрипта)
Результат выполнения скрипта:
$ ./test.sh qwerty Вы запустили скрипт с именем ./test.sh и параметром qwerty Вы запустили скрипт с именем $script_name и параметром $parametr1
После того как мы познакомились как использовать переменные и передавать скрипту параметры, время познакомиться с зарезервированными переменными:
$DIRSTACK — содержимое вершины стека каталогов $EDITOR — текстовый редактор по умолчанию $EUID — Эффективный UID. Если вы использовали программу su для выполнения команд от другого пользователя, то эта переменная содержит UID этого пользователя, в то время как. $UID — . содержит реальный идентификатор, который устанавливается только при логине. $FUNCNAME — имя текущей функции в скрипте. $GROUPS — массив групп к которым принадлежит текущий пользователь $HOME — домашний каталог пользователя $HOSTNAME — ваш hostname $HOSTTYPE — архитектура машины. $LC_CTYPE — внутренняя переменная, котороя определяет кодировку символов $OLDPWD — прежний рабочий каталог $OSTYPE — тип ОС $PATH — путь поиска программ $PPID — идентификатор родительского процесса $SECONDS — время работы скрипта(в сек.) $# — общее количество параметров переданных скрипту $* — все аргументы переданыне скрипту(выводятся в строку) $@ — тоже самое, что и предыдущий, но параметры выводятся в столбик $! — PID последнего запущенного в фоне процесса $$ — PID самого скрипта
Условия
Условные операторы, думаю, знакомы практически каждому, кто хоть раз пытался на чем-то писать программы. В bash условия пишутся след. образом (как обычно на примере): #!/bin/bash source=$1 #в переменную source засовываем первый параметр скрипта dest=$2 #в переменную dest засовываем второй параметр скрипта
if [[ «$source» -eq «$dest» ]] # в ковычках указываем имена переменных для сравнения. -eq — логическое сравнение обозначающие «равны» then # если они действительно равны, то echo «Применик $dest и источник $source один и тот же файл!» #выводим сообщение об ошибке, т.к. $source и $dest у нас равны exit 1 # выходим с ошибкой (1 — код ошибки) else # если же они не равны cp $source $dest # то выполняем команду cp: копируем источник в приемник echo «Удачное копирование!» fi #обозначаем окончание условия.
Результат выполнения скрипта: ite@ite-desktop:
$ ./primer2.sh 1 1 Применик 1 и источник 1 один и тот же файл! ite@ite-desktop:
$ ./primer2.sh 1 2 Удачное копирование!
Структура if-then-else используется следующим образом: if then
else
В качестве команд возвращающих код возврата могут выступать структуры [[ , [ , test, (( )) или любая другая(или несколько) linux-команда. test — используется для логического сравнения. после выражения, неоьбходима закрывающая скобка «]» [ — синоним команды test [[ — расширенная версия «[» (начиная с версии 2.02)(как в примере), внутри которой могут быть использованы || (или), & (и). Долна иметь закрывающуб скобку «]]» (( )) — математическое сравнение. для построения многоярусных условий вида: if . then . else if . then. else .
для краткости и читаемости кода, можно использовать структуру: if .. then . elif . then . elif .
Условия. Множественный выбор
Если необходимо сравнивать какоую-то одну переменную с большим количеством параметров, то целесообразней использовать оператор case. #!/bin/bash echo «Выберите редатор для запуска:» echo «1 Запуск программы nano» echo «2 Запуск программы vi» echo «3 Запуск программы emacs» echo «4 Выход» read doing #здесь мы читаем в переменную $doing со стандартного ввода
case $doing in 1) /usr/bin/nano # если $doing содержит 1, то запустить nano ;; 2) /usr/bin/vi # если $doing содержит 2, то запустить vi ;; 3) /usr/bin/emacs # если $doing содержит 3, то запустить emacs ;; 4) exit 0 ;; *) #если введено с клавиатуры то, что в case не описывается, выполнять следующее: echo «Введено неправильное действие»
esac #окончание оператора case.
Результат работы: ite@ite-desktop:
$ ./menu2.sh Выберите редатор для запуска: 1 Запуск программы nano 2 Запуск программы vi 3 Запуск программы emacs 4 Выход
После выбор цифры и нажатия Enter запуститься тот редактор, который вы выбрали(если конечно все пути указаны правильно, и у вас установлены эти редакторы 🙂 ) Прведу список логических операторв, которые используются для конструкции if-then-else-fi: -z # строка пуста -n # строка не пуста =, (==) # строки равны != # строки неравны -eq # равно -ne # неравно -lt,( ) #больше -ge,(>=) #больше или равно ! #отрицание логического выражения -a,(&&) #логическое «И» -o,(||) # логическое «ИЛИ»
С основами языка и условиями мы разобрались, чтобы не перегружать статью, разобью её на несколько частей(допустим на 3). Во второй части разберем операторы цикла и выполнение математических операций.
UPD: Исправил некоторые ошибки UPD: Обновил часть про условия if-then-else