트랩 명령을 사용하여 오류를 발생시키는 방법


13

우분투 12.04.2를 사용하고 있습니다. 쉘 스크립트에서 "trap"명령을 사용하여 비정상 또는 오류를 캡처하려고하지만 "Error"exit를 수동으로 트리거하려고합니다.

종료 1을 시도했지만 "오류"신호가 트리거되지 않습니다.

#!/bin/bash

func()
{
    exit 1
}

trap "echo hi" INT TERM ERR
func

"오류"종료 신호를 수동으로 트리거하는 방법을 모르십니까?

답변:


20

ERR트랩은 쉘 자체가 아닌 에러 코드와 함께 종료 할 때 코드를 실행하지만,하지 때 모든 명령 A의 일부가 아닌 그 쉘이 실행 조건 (처럼 if cmd..., 또는 cmd || ...비 제로와 ...) 종료 종료 상태 ( set -e쉘을 종료시키는 원인과 동일한 조건 ).

종료 상태가 0이 아닌 쉘 종료시 코드를 실행 EXIT하려면 대신 트랩을 추가 하고 확인하십시오 $?.

trap '[ "$?" -eq 0 ] || echo hi' EXIT

그러나 트랩 된 신호에서 신호 트랩과 EXIT 트랩이 모두 실행되므로 다음과 같이 수행 할 수 있습니다.

unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
  ret=$?
  if [ -n "$killed_by" ]; then
    echo >&2 "Ouch! Killed by $killed_by"
    exit 1
  elif [ "$ret" -ne 0 ]; then
    echo >&2 "Died with error code $ret"
  fi' EXIT

또는 $((signum + 128))신호 와 같이 종료 상태를 사용하려면

for sig in INT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT

그러나 SIGINT 또는 SIGQUIT에서 정상적으로 종료하면 상위 프로세스가 터미널 인터럽트 bash대기 및 협업 종료 처리 를 구현 하는 쉘과 같은 경우에는 성가신 부작용이 발생할 수 있습니다 . 따라서 부모에게 실제로 중단되었으며 SIGINT / SIGQUIT를 받았을 때 자신을 종료해야한다고보고하기 위해 대신 동일한 신호로 자신을 죽이는 것이 좋습니다.

unset killed_by
for sig in INT QUIT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
  if [ -n "$killed_by" ]; then
    trap - "$killed_by" # reset handler
    # ulimit -c 0 # possibly disable core dumps
    kill -s "$killed_by" "$$"
  else
    exec "$ret"
  fi' EXIT

당신이 원하는 경우 ERR화재 트랩을 그냥 0이 아닌 종료와 같은 상태로 명령을 실행 false또는 test.


6

종료하지 않고 return을 사용하여 함수 종료시 상태를 설정하십시오 (반환없이 함수가 실패하면 상태는 마지막으로 실행 된 명령문의 상태입니다). 질문의 예에서 대체 return하는 경우 다음 exit과 같이 작동합니다. 나는 당신이 의도했다고 생각합니다 : 트랩은 ERR 의사 신호에서 트리거되고 'hi'가 인쇄됩니다. 추가 고려 사항을 보려면 다음을 시도하십시오.

#!/bin/bash

func()
{
    echo 'in func'
    return 99
    echo 'still in func'
}

trap 'echo "done"' EXIT
trap 'status=$?; echo "error status is $status"; trap - EXIT; exit $status' ERR
func
echo 'returned from func'

0 리턴, ERR 트랩 주석 처리, ERR 핸들러 내 EXIT 트랩 취소, ERR 핸들러 종료 또는 리턴 제거 및 falsefunc의 마지막 명령문으로 설정 과 같은 다양한 수정을 시도 할 수 있습니다 .

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