![sigterm의 이상한 AWS 동기화 동작](https://linux55.com/image/165969/sigterm%EC%9D%98%20%EC%9D%B4%EC%83%81%ED%95%9C%20AWS%20%EB%8F%99%EA%B8%B0%ED%99%94%20%EB%8F%99%EC%9E%91.png)
이것은 나에게 혼란스러운 행동입니다. aws s3sync 명령이 실행되는 동안 스크립트에 종료 신호를 보냈고 sigterm 오류를 처리했지만 오류 트랩도 awssync 명령에 의해 트리거되었으며 그 이유를 이해할 수 없습니다. 더욱 혼란스러운 점은 명령이 오류를 발생시키고 계속된다는 것입니다.
스크립트:
#! /bin/bash
trap 'echo GOT ERROR, exiting' ERR
trap 'echo GOT SIGTERM!' SIGTERM
while true; do
date +%F_%T
aws s3 cp /vagrant/audio/ s3://testarchive/tester/ --recursive
sleep 1
done
스크립트를 실행하는 명령:
timeout 5s ./tester.sh
산출:
upload: ../../vagrant/audio/2019-09-16/3/35322118-8264-406B-961B-EAF1FE7A34EF.wav to s3://testarchive/tester/2019-09-16/3/35322118-8264-406B-961B-EAF1FE7A34EF.wav
upload: ../../vagrant/audio/2019-09-16/1/165BD3D0-773A-4591-A43E-D67810716066.wav to s3://testarchive/tester/2019-09-16/1/165BD3D0-773A-4591-A43E-D67810716066.wav
upload: ../../vagrant/audio/2019-09-16/2/2A9559BB-168A-47D2-943A-A51B7885233B.wav to s3://testarchive/tester/2019-09-16/2/2A9559BB-168A-47D2-943A-A51B7885233B.wav
Terminated6.8 MiB/123.1 MiB (1.5 MiB/s) with 422 file(s) remaining
GOT ERROR, exiting
GOT SIGTERM!
2020-01-17_21:05:40
upload: ../../vagrant/audio/2019-09-16/0/07502A17-9304-4995-94E1-A1B0D439EEE7.wav to s3://testarchive/tester/2019-09-16/0/07502A17-9304-4995-94E1-A1B0D439EEE7.wav
upload: ../../vagrant/audio/2019-09-16/0/05E4C765-C2FA-4EC0-9803-8FF02C0FEDDE.wav to s3://testarchive/tester/2019-09-16/0/05E4C765-C2FA-4EC0-9803-8FF02C0FEDDE.wav
upload: ../../vagrant/audio/2019-09-
편집 #2:
29 1 * * * root strace -e trace=kill timeout --foreground 6 /home/vagrant/tester.sh &> /home/vagrant/tester.log
#! /bin/bash
trap 'echo GOT ERROR..' ERR
trap 'echo GOT SIGTERM! && set_terminate_flag' SIGTERM
terminate_flag=false
function set_terminate_flag {
terminate_flag=true
}
while true; do
if [ "$terminate_flag" = true ]; then
echo OMG IT WORKS!
exit 0
fi
date +%F_%T
aws s3 cp /vagrant/audio/ s3://testarchive/tester/ --recursive
echo LOOP IS Done, begin sleep
done
산출:
...(skip output, 6 seconds have passed!!!)
--- SIGALRM {si_signo=SIGALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=14831664, ptr=0xe25030}} ---
kill(9432, SIGTERM) = 0
kill(9432, SIGCONT) = 0
...(skip output)
upload: ../vagrant/audio/2020-01-01/E7914F83-8A89-4679-ABBC-8DB261D13349-01.wav to s3://testarchive/tester/2020-01-01/E7914F83-8A89-4679-ABBC-8DB261D13349-01.wav
GOT SIGTERM!
LOOP IS Done, begin sleep
OMG IT WORKS!
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9432, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 124 +++
답변1
trap 'echo GOT ERROR, exiting' ERR
단순히 "종료"라고 말하면 종료된다는 의미는 아닙니다 ;-)
ERR
트랩은 명령이 있을 때마다 실행됩니다.실패하다, 이후에 스크립트가 즉시 종료되는지 여부에 관계없이(예: 왜냐하면 set -e
):
$ bash -c 'trap "echo error, not exiting yet" ERR; false; echo DONE'
error, not exiting yet
DONE
귀하의 경우 실패한 명령은 date
또는 일 수 있지만 aws
가능성이 가장 높습니다 sleep
(이것은 내장 명령이 아닌 외부 명령입니다). sleep
0이 아닌 상태로 종료합니다(=실패하여 ERR
트랩을 트리거함). 전송된 신호에 의해 종료되었기 때문입니다 timeout
. timeout
먼저 자식에게, 그 다음에는 전체 자식에게프로세스 그룹그것은 다음의 일부입니다:
$ strace -e trace=kill timeout 1s bash -c 'echo $$; while :; do sleep 3600; done
'
4851
...
kill(4851, SIGTERM) = 0
kill(0, SIGTERM) = 0
...
쉘은 다음까지 어떤 트랩도 실행하지 않습니다.뒤쪽에timeout
전체 신호가 방출되지 않으면 기다리고 있던 전경 명령이 종료되었습니다.프로세스 그룹(옵션을 통해 달성할 수 있음 --foreground
) 전경 명령이 종료되지 않고 트랩이 실행되지 않을 수 있습니다.
$ timeout 1s bash -c 'trap "echo TERM caught" TERM; sleep 36000; echo DONE'
Terminated
TERM caught
DONE
$ timeout --foreground 1s bash -c 'trap "echo TERM caught" TERM; sleep 36000; echo DONE'
<wait and wait>