Подтвердить что ты не робот

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

Но есть способ написать функцию, которая прерывает выполнение, независимо от того, как она вызывается? Мне просто нужно получить реальное возвращаемое значение (эхо его функция).

4b9b3361

Ответ 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".

Ответ 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"