Есть ли способ написать функцию bash, которая прерывает выполнение, независимо от того, как она вызывается?
Я использовал оператор "exit 1" в моих bash функциях для завершения всего script, и он работал нормально:
function func()
{
echo "Goodbye"
exit 1
}
echo "Function call will abort"
func
echo "This will never be printed"
Но потом я понял, что он не выполняет работу при вызове типа:
res=$(func)
Я понимаю, что я создал подоболочку, а "exit 1" прерывает эту подоболочку, а не главную....
Но есть способ написать функцию, которая прерывает выполнение, независимо от того, как она вызывается? Мне просто нужно получить реальное возвращаемое значение (эхо его функция).
Ответы
Ответ 1
Что вы можете сделать, зарегистрируйте оболочку верхнего уровня для сигнала TERM
для выхода, а затем отправьте TERM
в оболочку верхнего уровня:
#!/bin/bash
trap "exit 1" TERM
export TOP_PID=$$
function func()
{
echo "Goodbye"
kill -s TERM $TOP_PID
}
echo "Function call will abort"
echo $(func)
echo "This will never be printed"
Итак, ваша функция отправляет сигнал TERM
обратно в оболочку верхнего уровня, которая захватывается и обрабатывается с помощью предоставленной команды, в этом случае "exit 1"
.
Ответ 2
Вы можете использовать set -e
, который завершает, если команда завершает работу с ненулевым статусом:
set -e
func
set +e
Или возьмите возвращаемое значение:
(func) || exit $?
Ответ 3
Но есть ли способ написать функцию, которая прервет выполнение, независимо от того, как она называется?
Нет.
Мне просто нужно получить реальное возвращаемое значение (эхо его функция).
Вы можете
res=$(func)
echo $?
Ответ 4
Детский процесс не может принудительно закрыть родительский процесс. Вам нужно использовать какой-то механизм сигнализации. Параметры могут включать специальное возвращаемое значение или, возможно, отправить некоторый сигнал с помощью kill
, что-то вроде
function child() {
local parent_pid="$1"
local other="$2"
...
if [[ $failed ]]; then
kill -QUIT "$parent_pid"
fi
}
Ответ 5
Я думаю, лучше
#!/bin/bash
set -e
trap "exit 1" ERR
myfunc() {
set -x # OPTIONAL TO SHOW ERROR
echo "Exit with failure"
set +x # OPTIONAL
exit 1
}
echo "BEFORE..."
myvar="$(myfunc)"
echo "AFTER..But not shown"