В чем разница между оператором returnand exitв функциях Bash относительно кодов выхода?
В чем разница между оператором returnand exitв функциях Bash относительно кодов выхода?
Ответы:
С man bashна return [n];
Заставляет функцию прекратить выполнение и вернуть значение, указанное в n, вызывающей стороне. Если n опущено, возвращается статус последней команды, выполненной в теле функции.
... на exit [n]:
Заставить оболочку выйти со статусом n. Если n опущено, состояние выхода соответствует статусу последней выполненной команды. Ловушка EXIT выполняется перед завершением оболочки.
РЕДАКТИРОВАТЬ:
Согласно вашему редактированию вопроса, относительно кодов выхода, не returnимеет ничего общего с кодами выхода. Коды выхода предназначены для приложений / скриптов , а не функций. Таким образом, в этом отношении единственным ключевым словом, которое устанавливает код завершения скрипта (то, которое может быть перехвачено вызывающей программой с помощью $?переменной оболочки), является exit.
РЕДАКТИРОВАТЬ 2:
Мое последнее обращение со ссылкой exitвызывает некоторые комментарии. Он был сделан для того, чтобы различать returnи exitпонимать ОП, и фактически в любой точке скрипта программы / оболочки exitэто единственный способ завершить скрипт кодом выхода в вызывающий процесс.
Каждая команда выполняется в оболочке производит локальный «код выхода»: она устанавливает $?переменную к этому коду, и может быть использована с if, &&и другими операторами условно выполнять другие команды.
Эти коды выхода (и значение $?переменной) сбрасываются при каждом выполнении команды.
Между прочим, код выхода последней команды, выполняемой сценарием, используется в качестве кода выхода самого сценария, видимого вызывающим процессом.
Наконец, функции при вызове действуют как команды оболочки относительно кодов выхода. Код выхода функции ( внутри функции) устанавливается с помощью return. Поэтому, когда в функции return 0выполняется, выполнение функции прекращается, давая код выхода 0.
func(){ return 50; };func;echo $?повторяет 50. Таким образом, $?переменная оболочки, похоже, не ограничена exit.
$?Расширяется до состояния выхода последнего выполненного переднего конвейера». Этот выход может быть из оболочки в форме вызова exit(или попадания в конец скрипта) или в форме вызова returnвнутри функции.
$? Текущий процесс / сценарий ограничен exitили последним результатом команды, выполненной этим сценарием. Итак, если ваша последняя строка скрипта является вызовом этой функции, и эта функция возвращает 50, да, то, $?что вы производите для вызывающего вас процесса, равно 50. Однако это не имеет отношения к return, потому что это ограничено текущим сценарием. Возвращается только в том случае, если этот вызов функции является последним предложением скрипта. exitОднако всегда завершайте сценарий и возвращайте это значение как $? вызывающему процессу .
returnимеет никакого отношения к кодам выхода». Эксперимент показывает, что между кодом возврата функции и кодом выхода скрипта нет функциональной разницы.
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()
$?.
echo fnord | while read x; do exitfunc; done; echo "still here"будет печатать «все еще здесь». Похоже, что whileв этом сценарии происходит выход только из суб-оболочки.
done || exit $?но это некрасиво и не совсем эквивалентно.
returnприведет к тому, что текущая функция или исходный скрипт выйдут из области видимости```.
Я не думаю, что кто-то действительно полностью ответил на вопрос, потому что они не описывают, как они используются. Хорошо, я думаю, что мы знаем, что выход убивает скрипт, где бы он ни вызывался, и вы также можете присвоить ему статус, такой как выход или выход 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 предназначена только для ознакомительных целей. Это не должно быть то, как вы выполняете такую опцию в реальном скрипте.
test -d $1для достижения того же результата. Никогда не делай if <check> return else return. <check>один будет делать то же самое на всех языках, которые я знаю, по крайней мере.
isdirectory() { [ -d "$1" ]; }будет вести себя точно так же, как и здесь: возвращаемое по умолчанию значение функции оболочки, достигая конца ее кода или returnаргумента без аргументов, - это значение самая последняя команда.
returnутверждения. Это правда, что его пример является упрощенным и не должен использоваться в производстве. Но это просто, так что он отлично справляется со своей задачей. Ничего плохого в этом нет.
Помните, что функции являются внутренними для скрипта и обычно возвращаются из того места, откуда они были вызваны с помощью оператора return. Вызов внешнего сценария - это совсем другое дело, и сценарии обычно заканчиваются оператором выхода.
Разница «между оператором возврата и выхода в функциях BASH относительно кодов выхода» очень мала. Оба возвращают статус, а не значения как таковые. Нулевое состояние указывает на успех, а любое другое состояние (от 1 до 255) указывает на сбой. Оператор return вернется в сценарий с того места, где он был вызван, а оператор выхода завершит весь сценарий, где бы он ни встречался.
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, он просто прекратит обработку скрипта.
return: can only 'return' from a function or sourced script, что делает его непригодным для общего сценария.
allситуациях. Использование .или sourceзапуск сценария в текущей оболочке, а не создание вложенной оболочки. Сценарий должен знать, как его использовать. Горе тому, кто делает это наоборот. Лично я рекомендую прочитать сценарии, прежде чем запускать их в первый раз.
trapфункцию для, ERR EXITа затем сначала сохранить код завершения неудачной команды, errCode=$?а затем выйти из сценария (с источником или нет), return $errCode || exit $errCodeиспользуя ||средство «если я не могу вернуться, потому что я не был получен» просто выйдите вместо ".
Простыми словами (в основном для новичков в кодировании), мы можем сказать,
`return` : exits the function,
`exit()` : exits the program(called as process while running)
Также, если вы заметили, это очень просто, но ...,
`return` : is the keyword
`exit()` : is the function
exitэто не более или менее функция, чем return. Это встроенные команды. Они даже не зарезервированные слова.
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выйдет.
(и )помещает этот блок в под-оболочку, фактически не выполняя команду .(источник), как если бы вы обычно выполняли тестовый скрипт, который находится в под-оболочке. Если сценарий не запущен .или у sourceвас фактически есть 2 вложенных оболочки.
Вопрос ОП: В чем разница между оператором возврата и выхода в функциях BASH относительно кодов выхода?
Во-первых, требуется пояснение:
В приведенном выше списке маркеров выберите из «(x | y)» либо всегда первый элемент, либо всегда второй элемент, чтобы получить инструкции о функциях & return или shells & exit соответственно.
Что ясно, так это то, что они оба часто используют специальную переменную $? передать значения вверх после того, как они заканчиваются.
* Теперь о специальных способах, которые $? можно установить:
Стоит отметить, что $? можно присвоить значение, вызвав exit в вложенной оболочке, например так:
# (exit 259)
# echo $?
3
exit 259выводится как, 3потому что конечное значение выхода - один байт. 259 % 256 = 3
Прежде всего, returnэто ключевое слово, а exitмой друг - это функция.
Тем не менее, вот простейшие объяснения.
return
Возвращает значение из функции.
exit
Он выходит из текущей оболочки или покидает ее.
returnключевое слово. Возврат - это гораздо больше, чем просто коды выхода, поэтому сравнение несправедливо.
exitни returnв «ключевые слова», или, как Баш ручными называет их, «зарезервированные слова». Ни один из них не является «функцией», в смысле функции bash. Обе команды являются встроенными, в bash lingo. (Там является функция C стандартной библиотеки называется exit(), и язык программирования Си имеет зарезервированное слово return, но те , которые не следует путать с командами Баша, даже если их семантика удивительно похожа.)
help <command>вашу оболочку, чтобы получить информацию о том, что будет делать встроенная оболочка. В вашем случаеhelp returnиhelp exit