쉘 스크립트 종료 코드 및 로깅

쉘 스크립트 종료 코드 및 로깅

STDERR 및 STDOUT을 두 화면에 보내고 이를 파일(test.log)에 기록하는 다음과 같은 간단한 쉘 스크립트가 있습니다. 또한 종료 시 적절한 종료 코드를 사용하여 종료하려고 합니다.

이 코드에서는 첫 번째 메시지(블록 내)를 에코하고 종료하기를 원합니다. 그러나 두 명령문을 모두 에코하고 항상 0으로 종료됩니다.

$ cat test.sh
#!/bin/ksh

n_exitstatus=0

{
  n_exitstatus=1
  echo "Inside block : $n_exitstatus"
  exit $n_exitstatus
}  2>&1 | tee -a test.log

echo "Before last exit : $n_exitstatus"
exit $n_exitstatus
$ sh test.sh
Inside block : 1
Before last exit : 0
$ echo $?
0

첫 번째 명령문을 에코한 후 즉시 종료되도록(화면과 파일에 기록되도록) 이 스크립트를 어떻게 수정합니까?

답변1

파이프라인에서 내부 코드 블록을 사용할 수 있습니다. 이렇게 하면 쉘이 서브쉘을 실행하게 됩니다. Exit는 기능만 남깁니다. 파이프를 제거하면 | tee -a test.log예상대로 작동합니다.

따라서 가장 간단한 해결책은 블록에서 파이프를 제거하고 내부 echo 명령 뒤에 배치하는 것입니다.

블록을 본문으로 사용하여 함수를 생성하고 이를 실행한 다음 반환 값을 사용하여 외부 코드를 추가로 실행하기 전에 종료할지 결정할 수도 있습니다.

편집하다 다음은 유용한 링크입니다:http://www.bolthole.com/solaris/ksh-functions.html

답변2

이는 다음 질문과 밀접한 관련이 있습니다.호출 방법에 관계없이 전체 실행을 중단하는 bash 함수를 작성하는 방법이 있습니까?

주어진 솔루션 구현수락된 답변, 우리는 이것을 가지고 있습니다 :

$ cat test.ksh
#!/bin/ksh

trap 'exit $n_exitstatus' TERM

SCRIPT_PID="$$"

n_exitstatus=0

{
    n_exitstatus=1
    echo "Inside block: $n_exitstatus"

    kill -s TERM $SCRIPT_PID

}  2>&1 | tee -a test.log

echo "Before last exit: $n_exitstatus"
exit $n_exitstatus
$ chmod +x test.ksh
$ ./test.ksh
Inside block: 1
$ cat test.log
Inside block: 1

유일하게 옳지 않은 점은 스크립트의 종료 상태가 1이 아닌 0이라는 것입니다. 이는 0이 있는 외부 범위에서 종료가 발생하기 때문입니다 $n_exitstatus.

관련 정보