Стоп-функция выхода без выхода из оболочки
Я писал script, а затем столкнулся с нечетной проблемой. Если бы я использовал script, который содержит кучу функций, которые могут вызывать функцию ошибки, которая выводит строку, а затем выходит из нее, она выйдет из моей оболочки. Я знаю, почему он это делает. Это связано с тем, что вызов функции находится в том же пространстве процесса, что и вызывающий (по крайней мере, он находится в bash), поэтому выход внутри функции завершает текущий процесс с предоставленным кодом выхода. Пример:
error()
{
echo $1
exit 1
}
fn()
{
if [ $# == 0 ]; then
error "Insufficient parameters."
fi
# do stuff
}
$ fn
Insufficient parameters.
[shell terminates]
Итак, мой вопрос: могу ли я выйти из всех функций в стеке функций, не прерывая текущую оболочку и не создавая новую подоболочку?
Спасибо
Ответы
Ответ 1
Чтобы выйти из стека функций без выхода из оболочки, можно воспользоваться командой:
kill -INT $$
Как указано pizza, это похоже на нажатие Ctrl-C, которое остановит текущий script и запустит его в командной строке.
Примечание: единственная причина, по которой я не выбрал pizza, - это потому, что это было похоронено в его/ее ответе и не отвечало напрямую.
Ответ 2
вы можете сделать
exit() { return $1;}
то
source ./your_script
В ответ на скептиков это влияет только на текущую оболочку, это не влияет на снаряды, которые вы создаете.
Более информативная форма может быть
exit() {
local ans
local line
read -p "You really want to exit this? " line
ans=$(echo $line)
case "$ans" in
Y);;
y);;
*)kill -INT $$;;
esac
unset -f exit
exit $1
}
Ответ 3
Вам нужно добавить операторы return
к каждой из ваших функций, чтобы проверить возвращаемое значение любых функций, которые они вызывают поочередно. Поиск файла похож на резку и вставку кода в текущий контекст с небольшим исключением переменных, таких как $BASH_SOURCE
.
В качестве альтернативы вы можете определить fn
как оболочку script, так что exit
будет делать то, что вы хотите (если вилка слишком дорога).
Ответ 4
с помощью оператора return
, но вам нужно добавить return после вызова ошибки
Ответ 5
В оболочке нет механизма исключения для перемотки через многие вызовы функций одновременно. Вам нужно просто проверить возвращаемые значения и вручную вернуться полностью вниз.