Разница между возвратом и выходом в функциях Bash

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

11 ответов

Решение

От man bash на return [n];

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

... на exit [n]:

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

РЕДАКТИРОВАТЬ:

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

РЕДАКТИРОВАТЬ 2:

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

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

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

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

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

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

#!/bin/bash

retfunc()
{
    echo "this is retfunc()"
    return 1
}

exitfunc()
{
    echo "this is exitfunc()"
    exit 1
}

retfunc
echo "We are still here"
exitfunc
echo "We will never see this"

Выход

$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()

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

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

    #!/bin/bash
    isdirectory() {
      if [ -d "$1" ]
      then
        return 0
      else
        return 1
      fi
    echo "you will not see anything after the return like this text"
    }

проверьте вот так:

    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi

или вот так:

    isdirectory || echo "not a directory"

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

Для получения дополнительной информации о функциях: http://www.linuxjournal.com/content/return-values-bash-functions

ПРИМЕЧАНИЕ. Функция isdirectory предназначена только для ознакомительных целей. Это не должно быть то, как вы выполняете такую ​​опцию в реальном скрипте.

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

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

return 0  # returns to where the function was called.  $? contains 0 (success).

return 1  # returns to where the function was called.  $? contains 1 (failure).

exit 0  # exits the script completely.  $? contains 0 (success).

exit 1  # exits the script completely.  $? contains 1 (failure).

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

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

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

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

. a.sh

Если вы включите exit в a.sh, он не только завершит работу сценария, но и завершит сеанс оболочки.

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

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

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

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

#!/bin/bash
function die(){
   echo ${1:=Something terrible wrong happen}
   #... clean your trash
   exit 1
}

[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"

делать следующее:

user$ ./test
Whatever is not available
user$

test и оболочка закроется.

user$ . ./test
Whatever is not available

только test закончится и подсказка покажет.

Решение состоит в том, чтобы заключить потенциально ( а также )

#!/bin/bash
function die(){
   echo $(1:=Something terrible wrong happen)
   #... clean your trash
   exit 1
}

( # added        
    [ -f /whatever/ ] || die "whatever is not available"
    # now we can proceed
    echo "continue"
) # added

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

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

`return` : exits the function,
`exit()` : exits the program(called as process while running)

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

`return` : is the keyword
`exit()` : is the function

Вопрос ОП: Чем отличается оператор возврата и выхода в функциях BASH от кодов выхода?

Во-первых, требуется пояснение:

  • Оператор (return|exit) не требуется для прекращения выполнения (function|shell). (Функция | shell) завершится, когда достигнет конца списка кодов, даже без оператора (return|exit).
  • Оператор (return|exit) не требуется для передачи значения обратно из прекращенного (function|shell). Каждый процесс имеет встроенную переменную $? который всегда имеет числовое значение. Это специальная переменная, которая не может быть установлена ​​как "?=1", но устанавливается только специальными способами (см. Ниже *). Значение $? после последней команды, которая должна быть выполнена в (вызываемой функции | вложенной оболочке) - значение, которое передается обратно (вызывающая функция | родительская оболочка). Это верно независимо от того, является ли последняя выполненная команда ("return [n]"| "exit [n]")) или простой ("return", или что-то еще, что оказывается последней командой в коде вызываемых функций).

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

Что ясно, так это то, что они оба часто используют специальную переменную $? передать значения вверх после того, как они заканчиваются.

* Теперь о специальных способах, которые $? можно установить:

  • Когда вызываемая функция завершается и возвращается к своему вызывающему, тогда $? в звонилке будет равно итоговое значение $? в завершенной функции.
  • Когда родительская оболочка имплицитно или явно ожидает единственную вложенную оболочку и освобождается по окончании этой вспомогательной оболочки, тогда $? в родительской оболочке будет равно итоговое значение $? в завершенной субоболочке.
  • Некоторые встроенные функции могут изменять $? в зависимости от их результата. Но некоторые этого не делают.
  • Встроенные функции "возврат" и "выход", когда после числового аргумента указывается $? с аргументом и прекратить выполнение.

Стоит отметить, что $? можно присвоить значение, вызвав exit в вложенной оболочке, например так:

# (exit 259)
# echo $?
3  

Если вы конвертируете сценарий bash в функцию, вы обычно заменяете exit N с участием return N. Код, вызывающий функцию, будет обрабатывать возвращаемое значение так же, как код выхода из подпроцесса.

С помощью exit внутри функции приведет к завершению всего скрипта.

Добавление действенного аспекта к нескольким другим ответам:

Оба могут давать коды выхода - по умолчанию или определенные функцией, и единственный "по умолчанию" - ноль для успеха как для выхода, так и для возврата. Любой статус может иметь произвольный номер от 0 до 255, в том числе и для успеха.

Возврат часто используется для интерактивных сценариев, которые выполняются в текущей оболочке и вызываются с помощью например, и просто возвращает вас в вызывающую оболочку. После этого код возврата становится доступным для вызывающей оболочки: дает вам определенный статус возврата. Exit в этом случае также закрывает вашу оболочку (включая соединения SSH, если вы так работаете).

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

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

Тем не менее, вот простейшие объяснения.

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

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

Другие вопросы по тегам