Разница между возвратом и выходом в функциях Bash - PullRequest
375 голосов
/ 12 декабря 2010

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

Ответы [ 9 ]

275 голосов
/ 12 декабря 2010

С man bash по return [n];

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

... в exit [n]:

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

EDIT:

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

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

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

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

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

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

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

267 голосов
/ 12 декабря 2010

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()
49 голосов
/ 16 октября 2013

Я не думаю, что кто-то действительно полностью ответил на вопрос, потому что они не описывают, как они используются. Хорошо, я думаю, что мы знаем, что выход убивает скрипт, где бы он ни вызывался, и вы также можете присвоить ему статус, такой как выход или выход 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 предназначена только для ознакомительных целей. Это не должно быть то, как вы выполняете такую ​​опцию в реальном скрипте.

29 голосов
/ 06 сентября 2013

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

21 голосов
/ 11 июля 2014

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

. a.sh

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

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

6 голосов
/ 03 апреля 2015

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

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

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

`return` : is the keyword
`exit()` : is the function
5 голосов
/ 16 августа 2017
  • 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.

2 голосов
/ 20 марта 2018

Вопрос ОП: В чем разница между оператором возврата и выхода в функциях 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  
1 голос
/ 21 октября 2016

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

Тем не менее, вот простейшее объяснение. Возвращает значение из функции.

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

...