Для управления ходом выполнения цикла служат команды break и continue [1] и точно соответствуют своим аналогам в других языках программирования. Команда break прерывает исполнение цикла, в то время как continue передает управление в начало цикло, минуя все последующие команды в теле цикла.
Пример 10-20. Команды break и continue в цикле
Команде break может быть передан необязательный параметр. Команда break без параметра прерывает тот цикл, в который она вставлена, а break N прерывает цикл, стоящий на N уровней выше (причем 1-й уровень — это уровень текущего цикла, прим. перев.).
Пример 10-21. Прерывание многоуровневых циклов
Команда continue, как и команда break, может иметь необязательный параметр. В простейшем случае, команда continue передает управление в начало текущего цикла, а команда continue N прерывает исполнение текущего цикла и передает управление в начало внешнего цикла, отстоящего от текущего на N уровней (причем 1-й уровень — это уровень текущего цикла, прим. перев.).
Пример 10-22. Передача управление в начало внешнего цикла
Пример 10-23. Живой пример использования «continue N»
Конструкция continue N довольно сложна в понимании и применении, поэтому, вероятно лучше будет постараться избегать ее использования.
Примечания
Эти команды являются встроенными командами языка сценариев командной оболочки (shell), в то время как while, case и т.п. — являются зарезервированными словами.
Источник
Команда exit в Bash и коды выхода
Часто при написании сценариев Bash вам необходимо завершить сценарий при выполнении определенного условия или выполнить действие на основе кода выхода команды.
В этой статье мы рассмотрим встроенную команду exit Bash и статусы выхода выполненных команд.
Статус выхода
Каждая команда оболочки возвращает код выхода, когда она завершается успешно или безуспешно.
По соглашению нулевой код выхода указывает, что команда завершилась успешно, а ненулевое значение означает, что произошла ошибка.
Специальная переменная $? возвращает статус выхода последней выполненной команды:
Команда date завершена успешно, код выхода равен нулю:
Если вы попытаетесь запустить ls в несуществующем каталоге, код выхода будет отличным от нуля:
Код состояния можно использовать для выяснения причины сбоя команды. На странице руководства каждой команды содержится информация о кодах выхода.
При выполнении многокомандного конвейера статус выхода конвейера соответствует состоянию последней команды:
В приведенном выше примере echo $? напечатает код выхода команды tee .
Команда exit
Команда exit закрывает оболочку со статусом N Он имеет следующий синтаксис:
Если N не задано, код состояния выхода — это код последней выполненной команды.
При использовании в сценариях оболочки значение, указанное в качестве аргумента команды exit возвращается оболочке как код выхода.
Примеры
Статус выхода команд может использоваться в условных командах, таких как if . В следующем примере grep завершит работу с нулем (что означает истину в сценариях оболочки), если «строка поиска» найдена в filename :
При запуске списка команд, разделенных && (И) или || (ИЛИ), статус выхода команды определяет, будет ли выполнена следующая команда в списке. Здесь команда mkdir будет выполнена, только если cd вернет ноль:
Если сценарий завершается exit без указания параметра, код выхода из сценария — это код последней команды, выполненной в сценарии.
Использование только exit — это то же самое, что и exit $? или пропуская exit .
Вот пример, показывающий, как завершить сценарий, если он запущен пользователем без полномочий root:
Если вы запустите сценарий как root, код выхода будет нулевым. В противном случае скрипт выйдет со статусом 1 .
Выводы
Каждая команда оболочки возвращает код выхода при завершении. Команда exit используется для выхода из оболочки с заданным статусом.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
В этом руководстве мы познакомим вас с основами 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, оценивая заданные условия.
Источник
Как лучше делать выход из if-then?
Проверяется наличие каталога, если он есть, то нужно выполнить команды после fi, если нет (else) — создать каталог. Как лучше прекратить выполнение if-then в случае наличия каталога? Я не придумал ничего лучше, чем сделать так:
Ойбл, а я ! перед скобкой тыкал и удивлялся почему не работает. Ладно, спасибо.
Тут другой вопрос — нужно ли выходить из if.
Всегда мучает вопрос — что лучше — выполнить тело функции внутри if или после.
Надеюсь понятно что это диалект клингонского.
Если у тебя есть некий блок кода (функция, например), из которого нужно выходить в случае чего (ошибки, например), то тело пиши после if. А если есть возможность обрабатывать исключения — выходи из функции сигнализировав исключение. Ку?
А ещё есть true, false и ;
С исключениями очевидно. Но почему тело после if? Вроде как тело внутри if выглядит более логичным — всегда ясно что мы обработали все что нужно в if. С другой стороны я так делаю только если функция в 3-4 строки, а в остальных случаях пишу после if — типа вначале все обработали и «гуляем» спокойно.
Щас придут лисперы и подробно тебе объяснят на десяти страницах.
а зачем проверять?
mkdir -p $TRUNK_NAME
Конечно же только второй вариант. Он даже чисто визуально менее загроможден, такой код легче читать. Представь ситуацию, тебе надо понять код
К тому моменту как ты дочитаешь до else, врубаясь в алгоритм, ты потеряешь контекст и прийдется отматывать назад, чтоб посмотреть почему кидается ошибка.
Насколько лаконичней и элегантней смотрится
Ну вот поэтому в больших функциях так и делаю. Но хотелось единообразия. Раз такой вариант набрал больше всего голосов — буду использовать его все время.
Источник
Как использовать коды завершения в Bash-скриптах
Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.
Что такое коды завершения
В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.
Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.
Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.
Что происходит, когда коды завершения не определены
В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.
Этот скрипт запускает команды touch и echo . Если запустить этот скрипт без прав суперпользователя, команда touch не выполнится. В этот момент мы хотели бы получить информацию об ошибке с помощью соответствующего кода завершения. Чтобы проверить код выхода, достаточно ввести в командную строку специальную переменную $? . Она печатает код возврата последней запущенной команды.
Как видно, после запуска команды ./tmp.sh получаем код завершения 0 . Этот код говорит об успешном выполнении команды, хотя на самом деле команда не выполнилась. Скрипт из примера выше исполняет две команды: touch и echo . Поскольку код завершения не определён, получаем код выхода последней запущенной команды. Это команда echo , которая успешно выполнилась.
Если убрать из скрипта команду echo , можно получить код завершения команды touch .
Поскольку touch в данном случае — последняя запущенная команда, и она не выполнилась, получаем код возврата 1 .
Как использовать коды завершения в Bash-скриптах
Удаление из скрипта команды echo позволило нам получить код завершения. Что делать, если нужно сделать разные действия в случае успешного и неуспешного выполнения команды touch ? Речь идёт о печати stdout в случае успеха и stderr в случае неуспеха.
Проверяем коды завершения
Выше мы пользовались специальной переменной $? , чтобы получить код завершения скрипта. Также с помощью этой переменной можно проверить, выполнилась ли команда touch успешно.
После рефакторинга скрипта получаем такое поведение:
Если команда touch выполняется с кодом 0 , скрипт с помощью echo сообщает об успешно созданном файле.
Если команда touch выполняется с другим кодом, скрипт сообщает, что не смог создать файл.
Любой код завершения кроме 0 значит неудачную попытку создать файл. Скрипт с помощью echo отправляет сообщение о неудаче в stderr .
Создаём собственный код завершения
Наш скрипт уже сообщает об ошибке, если команда touch выполняется с ошибкой. Но в случае успешного выполнения команды мы всё также получаем код 0 .
Поскольку скрипт завершился с ошибкой, было бы не очень хорошей идеей передавать код успешного завершения в другую программу, которая использует этот скрипт. Чтобы добавить собственный код завершения, можно воспользоваться командой exit .
Теперь в случае успешного выполнения команды touch скрипт с помощью echo сообщает об успехе и завершается с кодом 0 . В противном случае скрипт печатает сообщение об ошибке при попытке создать файл и завершается с кодом 1 .
Как использовать коды завершения в командной строке
Скрипт уже умеет сообщать пользователям и программам об успешном или неуспешном выполнении. Теперь его можно использовать с другими инструментами администрирования или однострочниками командной строки.
В примере выше && используется для обозначения «и», а || для обозначения «или». В данном случае команда выполняет скрипт ./tmp.sh , а затем выполняет echo «bam» , если код завершения 0 . Если код завершения 1 , выполняется следующая команда в круглых скобках. Как видно, в скобках для группировки команд снова используются && и || .
Скрипт использует коды завершения, чтобы понять, была ли команда успешно выполнена. Если коды завершения используются некорректно, пользователь скрипта может получить неожиданные результаты при неудачном выполнении команды.
Дополнительные коды завершения
Команда exit принимает числа от 0 до 255 . В большинстве случаев можно обойтись кодами 0 и 1 . Однако есть зарезервированные коды, которые обозначают конкретные ошибки. Список зарезервированных кодов можно посмотреть в документации.
Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.