쉘 스크립트의 오류 처리

쉘 스크립트의 오류 처리

run_script.sh나는 빈 파일을 생성하는 단계를 포함하는 쉘 스크립트를 작성했습니다 run_script.lck. cronjob은 쉘 스크립트를 호출할 때마다 를 확인합니다 run_script.lck. 잠금이 있으면 프로그램이 run_script.sh이미 실행 중이고 아직 완료되지 않았음을 의미합니다. 파일 은 run_script.lck프로그램이 끝나면 삭제됩니다.

문제는 쉘 스크립트가 충돌할 때 종료하기 전에 잠금 파일을 삭제하는 것입니다.

나는 다음 줄을 썼다 :

trap "rm -f run_script.lck" EXIT

그러나 다음과 같이 바람직하지 않게 잠긴 파일을 삭제합니다.

쉘 A에서 실행 run_script.sh하고 실행 중이면 잠금 파일이 생성됩니다. 그런 다음 쉘 B에서 다시 실행하면 스크립트가 이미 실행 중이므로 스크립트가 중단된다는 메시지가 나타납니다. 그러나 트랩은 쉘 B(중단된 스크립트를 종료함)의 신호를 포함하여 EXIT 신호를 수신하므로 잠금 파일을 삭제합니다. 셸 A의 스크립트는 여전히 실행 중이지만 잠금이 제거되었으며, run_script.sh다른 스크립트가 이미 실행 중인 동안 누구나 다른 스크립트를 다시 호출할 수 있습니다.

이 문제를 해결하는 방법을 아시나요?

답변1

잠금이 존재하는지 확인앞으로함정을 설정하세요.

답변2

Ignacio의 답변을 설명하기 위해(다음 프로토콜 사용: 먼저 잠금 파일이 있는지 확인한 다음 트랩을 설치) 다음과 같이 문제를 해결할 수 있습니다.

$ cat test2.sh
if [ -f run_script.lck ]; then
  echo Script $0 already running
  exit 1
fi
trap "rm -f run_script.lck" EXIT
# rest of the script ...

답변3

이는 오류 트랩을 설정하고 sh오류가 발생할 때 스크립트를 중단함으로써 수행됩니다( set -e). 예를 들어

$ cat test.sh
set -e
trap "echo foo" ERR
if [ $# == 1 ]; then
  exit 0
fi
false
$ bash test.sh
foo
$ bash test.sh 1
$

( $#매개변수 수는 어디에 있습니까?)

스크립트에서는 스크립트가 성공적으로 실행될 때(즉, 정상적인 프로그램 흐름이 끝날 때와 같이 충돌이 발생하지 않음) 트랩 명령이 실행되는지 확인하기만 하면 됩니다.

set -e종료 상태가 동일하지 않을 때마다 0스크립트 실행이 종료됨을 나타냅니다. 마찬가지로, set -u정의되지 않은 변수를 (우발적으로) 사용할 때마다 실행이 종료됩니다.

따라서 이 아이디어를 원래 사용 사례로 전환하면 솔루션은 다음과 같을 수 있습니다.

$ cat test.sh
set -e
trap "rm -f run_script.lck" ERR
if [ -f run_script.lck ]; then
  echo Script $0 is already running
  exit 1
fi
#
# do all the work ...
#
# no error until now
rm -f run_script.lck

관련 정보