Linux bash exit from function

Команда 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 используется для выхода из оболочки с заданным статусом.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Источник

Как использовать коды завершения в Bash-скриптах

Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.

Что такое коды завершения

В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.

Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.

Читайте также:  Создание скрипта для windows

Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.

Что происходит, когда коды завершения не определены

В 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 . Однако есть зарезервированные коды, которые обозначают конкретные ошибки. Список зарезервированных кодов можно посмотреть в документации.

Читайте также:  Windows nginx php server

Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.

Источник

Разница между return и exit в функциях Bash

в чем разница между return и exit оператор в функциях BASH относительно кодов выхода?

9 ответов

С man bash on return [n] ;

останавливает выполнение функции и возвращает вызывающему объекту значение, указанное n. Если значение n опущено, возвращается состояние последней команды, выполненной в теле функции.

вызовите выход оболочки со статусом n. Если N опущено, статус выхода-это статус последней выполненной команды. Ловушка на выходе выполняется раньше оболочка заканчивается.

EDIT:

согласно вашему редактированию вопроса, относительно кодов выхода, return не имеет ничего общего с коды выхода. Коды выхода предназначены для приложения/скрипты, а не функции. Поэтому в этом отношении единственное ключевое слово, которое задает код выхода скрипта (тот, который может быть пойман вызывающей программой с помощью $? переменной оболочки) составляет exit .

изменить 2:

мое последнее заявление по поводу exit вызывает некоторые замечания. Это было сделано, чтобы дифференцировать return и exit для понимания OP, и на самом деле, в любой заданная точка скрипта программы / оболочки, exit является единственным способом завершения сценария с кодом выхода из вызывающего процесса.

каждая команда, выполняемая в оболочке, создает локальный «код выхода»: он устанавливает $? переменная к этому коду, и может быть использована с if , && и другие операторы для условного выполнения других команд.

эти коды выхода (и стоимостью $? variable) сбрасываются при каждом выполнении команды.

кстати, код выхода последней команды, выполняемой скриптом, используется в качестве кода выхода самого скрипта, как видно вызывающему процессу.

наконец, функции при вызове действуют как команды оболочки в отношении кодов выхода. Код выхода функции (внутри функция) устанавливается с помощью return . Итак, когда в функции return 0 выполняется, выполнение функции завершается, давая код выхода 0.

return приведет к выходу текущей функции из области видимости, в то время как exit приведет к завершению сценария в точке, где он вызывается. Вот пример программы, которая поможет объяснить это:

выход

Я не думаю, что кто действительно полностью ответил на вопрос, потому что они не описывают, как они используются. Хорошо, я думаю, мы знаем, что exit убивает скрипт, где бы он ни вызывался, и вы можете назначить ему статус, такой как exit или exit 0 или exit 7 и так далее. Это можно использовать для определения того, как сценарий был вынужден остановиться, если вызывается другим сценарием и т. д. Достаточно на выходе.

return при вызове вернет значение, указанное для указания функции поведение, обычно 1 или 0. Например:

в этом примере тест может использоваться для указания, был ли найден каталог. обратите внимание, что ничего после возврата не будет выполняться в функции. 0 истинно, но false равно 1 в оболочке, отличающейся от других прогов.

Примечание: функция isdirectory предназначена только для учебных целей. Это не должно быть так, как вы выполняете такую опцию в реальном скрипте.

помните, что функции являются внутренними для скрипта и обычно возвращаются оттуда, откуда они были вызваны с помощью оператора return. Вызов внешнего скрипта-это совсем другое дело, и скрипты обычно завершаются инструкцией exit.

разница «между оператором return и exit в функциях BASH относительно кодов выхода» очень мала. Оба возвращают статус, а не значения per se. Состояние ноль указывает на успех, в то время как любой другой статус (От 1 до 255) указывает на сбой. Оператор return вернется в сценарий, откуда он был вызван, в то время как оператор exit завершит весь сценарий, с которого он встречается.

Если ваша функция просто заканчивается без оператора return, статус последней выполненной команды возвращается как код состояния (и будет помещен в $? ).

Читайте также:  Windows 10 таблица роутинга

помните, возврат и выход возвращают код состояния от 0 до 255, доступный в $? . Нельзя вставьте что-нибудь еще в код состояния (например, Верните «cat»); это не сработает. Но сценарий может передать 255 различных причин сбоя с помощью кодов состояния.

вы можете установить переменные, содержащиеся в вызывающем скрипте, или результаты Эха в функции и использовать подстановку команд в вызывающем скрипте; но цель возврата и выхода-передать коды состояния, а не значения или результаты вычислений, как можно было бы ожидать на языке программирования, таком как C.

иногда, вы запускаете скрипт через . или source .

если вы включили exit на a.sh , он не просто завершит скрипт,но и завершит сеанс оболочки.

если вы включите return на a.sh , Он просто перестает обрабатывать скрипт.

простыми словами (в основном для новичков в кодировании), мы можем сказать,

также, если вы заметили, это очень основное, но.

exit завершить текущий процесс; С кодом выхода или без него, считайте это системой больше, чем функцией программы. Обратите внимание, что при поиске, exit завершит оболочку, однако, при запуске будет просто exit сценарий.

return функции вернитесь к инструкции после вызова, с кодом возврата или без него. return является необязательным и неявным в конце функции. return только может быть используется внутри функции.

я хочу добавить, что в то время как источник, это не просто exit скрипт изнутри функции, не убивая оболочку. Я думаю, пример лучше на тестовом скрипт

test -и — оболочка закроет.

только test завершится, и появится подсказка.

решение заключить потенциально процедура в ( и )

теперь, только в обоих случаях test выйдет.

прежде всего, return является ключевым словом и exit мой друг-функции.

тем не менее, вот самое простое объяснение.

return Он возвращает значение из функции.

exit Он выходит из текущей оболочки или покидает ее.

вопрос OP: В чем разница между оператором return и exit в функциях BASH относительно кодов выхода?

Firtly, некоторым требуется уточнение:

  • оператор (return|exit) не требуется для завершения выполнения (функции|оболочки). A (функция|оболочка) завершится, когда он достигнет конца своего списка кода, даже без оператора (return|exit).
  • оператор (return|exit) не требуется для передачи значения назад от завершенного (функция / оболочка). Каждый процесс имеет встроенную переменную $? который всегда имеет числовое значение. Это специальная переменная, которая не может быть установлена как «?=1», но устанавливается только специальными способами (см. ниже *). Стоимость $? после последней команды, выполняемой в (называемой function | sub shell), возвращается значение (function caller | parent shell). Это верно, является ли последняя выполненная команда («return [n]»| «exit [n]») или простой («return» или что-то еще else, который является последней командой в вызываемом коде функций.

в приведенном выше списке пуль выберите » (x / y)» либо всегда первый элемент, либо всегда второй элемент, чтобы получить инструкции о функциях & return или shells & exit соответственно.

что ясно, что они оба разделяют общее использование специальной переменной $? передавать значения вверх после их завершения.

* теперь для специальных способов, что $? может быть set:

  • когда вызываемая функция завершается и возвращается к вызывающему объекту, тогда$? в caller будет равно конечному значению $? в завершенной функции.
  • когда родительская оболочка impliciltly или явно ожидает на одной суб-оболочке и освобождается путем завершения этой суб-оболочки, то $? в родительской оболочке будет равно конечному значению $? в завершенной оболочке sub.
  • некоторые встроенные функции могут изменять $? в зависимости от их результат. Но некоторые нет.
  • встроенные функции «return» и «exit», когда за ними следует числовой аргумент both $? с аргументом и прекратить выполнение.

стоит отметить, что $? можно назначить значение, вызвав exit в sub shell, например:

Источник

Оцените статью