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

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

9 ответов


С man bash on return [n];

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

... on exit [n]:

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

EDIT:

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

изменить 2:

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

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

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

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

наконец, функции при вызове действуют как команды оболочки в отношении кодов выхода. Код выхода функции (внутри функция) устанавливается с помощью 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()

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

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

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

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

    if isdirectory ; 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. Вызов внешнего скрипта-это совсем другое дело, и скрипты обычно завершаются инструкцией exit.

разница "между оператором return и exit в функциях BASH относительно кодов выхода" очень мала. Оба возвращают статус, а не значения per se. Состояние ноль указывает на успех, в то время как любой другой статус (От 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).

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

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

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


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

. a.sh

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

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


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

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

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

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

  • 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 является ключевым словом и 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, например:

# (exit 259)
# echo $?
3