sigterm의 이상한 AWS 동기화 동작

sigterm의 이상한 AWS 동기화 동작

이것은 나에게 혼란스러운 행동입니다. 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(이것은 내장 명령이 아닌 외부 명령입니다). sleep0이 아닌 상태로 종료합니다(=실패하여 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>

おすすめ記事