Разница между возвратом и выходом в функциях 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, в том числе и для успеха.
Возврат часто используется для интерактивных сценариев, которые выполняются в текущей оболочке и вызываются с помощью
Выход необходим, если сценарий является исполняемым и вызывается из другого сценария или оболочки и выполняется в подоболочке. После этого коды выхода становятся доступными для вызывающей оболочки — в этом случае return выдаст ошибку.
Прежде всего, return
это ключевое слово и exit
мой друг это функция.
Тем не менее, вот простейшие объяснения.
return
Возвращает значение из функции.
exit
Он выходит из текущей оболочки или покидает ее.