호출 방법에 관계없이 전체 실행을 중단하는 bash 함수를 작성하는 방법이 있습니까?


83

전체 스크립트를 종료하기 위해 bash 함수에서 "exit 1"문을 사용했는데 제대로 작동했습니다.

function func()
{
   echo "Goodbye"
   exit 1
}
echo "Function call will abort"
func
echo "This will never be printed"

그러나 다음과 같이 호출하면 작업을 수행하지 않는다는 것을 깨달았습니다.

res=$(func)

나는 내가 서브 쉘을 생성했고 "exit 1"이 기본 서브 쉘이 아니라 그 서브 쉘을 중단한다는 것을 이해합니다 ....

그러나 호출 방법에 관계없이 전체 실행을 중단하는 함수를 작성하는 방법이 있습니까? 함수에 의해 반향되는 실제 반환 값을 가져 오면됩니다.

답변:


90

수있는 일은 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".


1
나는 C setsid()함수를 생각하고 있었지만 그것은 똑같은 방식으로 작동하지 않습니다. setsid새 프로세스를 시작해야하므로 명령을 사용하지 않도록 업데이트되었습니다 .
FatalError

3
공장. 모든 수준의 함수 중첩, 모든 흐름 ... 그냥 작동합니다.
LiMar

그것은 예를 들어, 첫 번째 인수의 코드를 사용하여 종료가이 중 일반 중단 () 함수를 만들 수 있나요 abort 2할 것 trap "exit 2" TERM전에 kill?
Neil C. Obremski 2013

@ NeilC.Obremski : 물론입니다. 주로 최상위 쉘로 다시 전파 할 값을 얻는 방법에 대한 문제입니다. 아마도 명령을 사용 tempfile하여 최상위 셸에 코드를 저장할 위치를 선택한 다음 종료중인 셸이 해당 파일에 코드를 쓰고 부모의 핸들러에서 읽기만하면됩니다.
FatalError 2011

2
중간에 서브 쉘이있을 때 작동하지 않는 것 같습니다. set -E 여기에서
Ron Burk

42

명령이 0이 아닌 상태로 종료되는 경우set -e 어떤 종료 를 사용할 수 있습니다 .

set -e 
func
set +e

또는 반환 값을 가져옵니다.

(func) || exit $?

3
흥미롭게도 나는 해결책을 봅니다. 기본 스크립트에서 "set -e"는 1을 반환하는 (또는 함께 종료하는) 모든 함수가 전체 실행을 중단하도록합니다. 불행히도 "set -e"는 모든 동작을 크게 변경하므로 사용할 수 없습니다.
LIMAR

1
숫자 비교에는 (())를 사용해야합니다. [] 내부 -gt, -eq 등을 사용해야합니다.
jordanm

16
또는res=$(func) || exit
글렌 잭맨

@glennjackman은 쿠키를 가져옵니다. 내가 가진 쓰레기보다 훨씬 더 깨끗합니다!
brice

3
그런 종류의 질문의 정신에 위배됩니다. 모든 함수 호출이 오류 자체를 포착해야한다면 exit 처음부터 사용할 필요가 없습니다 . 함수는 단순히 반환 할 수 있습니다. 경우 / 그러나, set -e전 세계적으로 설정되고,이 화장 좋은 감각 않습니다
phil294

2

자식 프로세스는 부모 프로세스를 암시 적으로 닫을 수 없습니다. 일종의 신호 메커니즘을 사용해야합니다. 옵션에는 특별한 반환 값이 포함되거나 kill다음과 같이 신호를 보낼 수 있습니다.

function child() {
    local parent_pid="$1"
    local other="$2"
    ...
    if [[ $failed ]]; then
        kill -QUIT "$parent_pid"
    fi
}

2

더 나은 것 같아요

#!/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"

0

그러나 호출 방법에 관계없이 전체 실행을 중단하는 함수를 작성하는 방법이 있습니까?

아니.

함수에 의해 반향되는 실제 반환 값을 가져 오면됩니다.

당신은 할 수 있습니다

res=$(func)
echo $?
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.