![쉘 스크립트의 오류 처리](https://linux55.com/image/17960/%EC%89%98%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98%20%EC%98%A4%EB%A5%98%20%EC%B2%98%EB%A6%AC.png)
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