bash에서 트랩 EXIT를 사용한 후 실행을 계속하는 방법은 무엇입니까?

bash에서 트랩 EXIT를 사용한 후 실행을 계속하는 방법은 무엇입니까?

환경:GNU bash, 버전 3.2.57(1)-릴리스(x86_64-apple-darwin20)

다른 함수의 종료를 포착하려고 시도하고 있지만 프로그램 실행을 계속합니다. 객체 지향 언어에서는 예외를 포착한 다음 다시 발생시키지 않고 실행을 계속할 수 있습니다. 이것이 바로 제가 원하는 것입니다. 함수를 기대하고 있지만 foo()exit경우에는 함수를 캡처하고 프로그램 실행을 계속하고 싶습니다.

#!/bin/bash

function doNotExitProgram()
{
   echo "Ignoring EXIT"
    # Magic happens here
}

trap doNotExitProgram EXIT

function foo()
{
    echo "Inside foo()"
    exit 170
}

foo
echo "Continue execution here"

예상되는:

foo() 내부는
EXIT를 무시
하고 여기서 실행을 계속합니다.

실제:

foo() 내부에서는
EXIT를 무시합니다.

지금까지 시도한 단계:

  1. EXIT를 사용해 보았지만 shopt -s extdebug작동하지 않는 것 같습니다.

  2. trap - EXIT내부에서 시도doNotExitProgram()

  3. 안으로 trap - EXIT돌아가려고 노력하다return 0doNotExitProgram()

  4. 안으로 trap - EXIT돌아가려고 노력하다return 1doNotExitProgram()

  5. return 0내부에서 시도doNotExitProgram()

  6. return 1내부에서 시도doNotExitProgram()

  7. trap "" EXIT내부에서 시도doNotExitProgram()

이 장면은 없음tldp.org의 함정또는트랩 매뉴얼 페이지.

편집하다:가능하다면 바꾸지 마세요.foo()

답변1

또는 도우미 기능을 사용하십시오.

#!/bin/bash

function doNotExitProgram()
{
   echo "Ignoring EXIT"
    # Magic happens here
}

function catchExitCode()
{
    case $1 in
        170 )
            doNotExitProgram
            ;;
    esac
}

trap 'catchExitCode $?' DEBUG

function foo()
{
    echo "Inside foo()"
    return 170
}

foo
echo "Continue execution here"

라는 분기 함수를 추가할 수 있습니다 catchExitCode. 단점은 다른 실행 파일이 반환되면 하이재킹될 수 있다는 것입니다 170. 고유한 종료 코드를 사용하면 논리를 분기할 수 있습니다.

답변2

사용 x옵션( bash -x file):

+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
+ doNotExitProgram
+ echo 'Ignoring EXIT'
Ignoring EXIT

trap doNotExitProgram EXITdoNotExitProgram호출은 호출될 때 발생합니다 exit. 호출되면 foo실행합니다 doNotExitProgram. exit스크립트 실행이 완료되어 실행되지 않습니다 echo "Continue execution here".

해결하다:

#!/bin/bash

(
  function doNotExitProgram()
  {
    echo "Ignoring EXIT"
      # Magic happens here
  }

  trap doNotExitProgram EXIT

  function foo()
  {
      echo "Inside foo()"
      exit 170
  }

  foo
)
echo "Continue execution here"

결과:

Inside foo()
Ignoring EXIT
Continue execution here

옵션 포함 x:

+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
++ doNotExitProgram
++ echo 'Ignoring EXIT'
Ignoring EXIT
+ echo 'Continue execution here'
Continue execution here

서브쉘에 트랩을 설정할 수 있습니다. 예상 값을 출력합니다.

답변3

exit함수를 사용하여 exit명령 숨기기

"도우미 기능" 솔루션과 유사하게
이는 기본 스크립트를 "계속 실행"하지 않습니다.

기본 스크립트의 "계속 실행"은 bash에서 수행되어야 합니다
.Bash에 "goto" 문이 있나요?

function evil_function() {
    echo "code before exit"
    exit 1
    echo "code after exit"
}

# shadow the exit command
function exit() {
    local rc=$?
    if [ -n "$1" ]; then rc=$1; fi
    echo "captured exit $rc"

    # no, this would continue "code after exit"
    #return $rc

    # restore the exit command
    unset -f exit

    # continue script here, then exit
    echo "exiting in 5 sec"
    sleep 5

    exit $rc
}

evil_function

# will not continue here

관련 정보