![반복되는 실행을 처리하는 방탄 방법](https://linux55.com/image/96874/%EB%B0%98%EB%B3%B5%EB%90%98%EB%8A%94%20%EC%8B%A4%ED%96%89%EC%9D%84%20%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94%20%EB%B0%A9%ED%83%84%20%EB%B0%A9%EB%B2%95.png)
내 라우터에는 30분마다 cron에 의해 실행되는 스크립트가 있습니다. 라우터는 때때로 몇 초 간격으로 두 번 실행되지만 라우터가 부팅될 때만 실행됩니다. 몇 주 전에 동시에 두 번 실행되는 것을 피하기 위해 pidof를 사용하여 확인하고 의도적으로 파일 잠금 방법을 피하여 가능한 문제를 방지했습니다.
for pid in $(pidof DoubleDDNS); do
if [ $pid != $$ ]; then
echo "DoubleDDNS [no2run] Exiting"
exit 1
fi
done
하지만. 방금 문제가 생겼습니다. 어떤 이유로 라우터가 실패했습니다. 내 대본은 분명히 끝나지 않았습니다. 영원히 기억에 남으세요. 따라서 위의 확인을 통해 원래(이전) 실행이 작업을 완료하지 않고 스크립트가 다시 실행되는 것을 방지할 수 있습니다. 이로 인해 문제가 발생합니다(새 WAN IP 주소가 DDNS에 보고되지 않음).
스크립트를 멈출 수 있는 명령이 없기 때문에 스크립트의 잘못이라고 생각하지 않습니다. 이 스크립트는 8개월 넘게 여러 라우터에서 아무런 문제 없이 실행되었습니다. 잘 작성되었으며 가능한 모든 버그를 처리하고 테스트합니다. 라우터는 대부분 잘 작동하지만, 그 안의 많은 부분이 깨졌습니다(SSL 등). 라우터는 3개의 메모리 위치가 가득 찼다고 보고하지 않습니다(사실일 수도 있고 아닐 수도 있음). 내 WebGUI에서 재설정을 선택하면 재설정되지 않으며 켜기/끄기 버튼을 사용하여 재설정해야 합니다!
그렇다면 내 수표가 두 번째로 실행되는지 어떻게 확인할 수 있나요? 내 생각에는 이전 인스턴스가 60초 이상 실행되었는지 확인하는 것도 포함됩니다.
- 오래된 인스턴스를 모두 종료해 보세요.
- 반복 실행에도 불구하고 계속됩니다. 스크립트는 매시간 3분과 33분에 실행되며 단일 실행은 15초 미만 동안 지속됩니다.
질문(파일을 생성하지 않는 것이 좋지만 파일 잠금을 피하는 것이 나쁜 해결책일 수 있으므로 제안함):
- 마지막 실행 시간을 감지하는 방법은 무엇입니까?
- 내 것보다 더 좋은 아이디어가 있나요?
- 스크립트를 종료하는 방법이 있습니까? 스크립트가 60초 이내에 완료되지 않으면 이 스크립트 인스턴스를 종료하세요.
기억하세요: 라우터, sh, 비지박스. 따라서 사용할 수 있는 것이 제한되어 있습니다. ASUS 라우터 ASUS RT-AC*U 라우터는 Merlin 펌웨어와 함께 사용됩니다.
답변1
이것은 제가 작업하는 방탄 버전의 모델입니다. 논리를 보여주기 위해 조작된 것입니다. 내 라우터에서는 잘 작동합니다.
#!/bin/sh
age_max_sec=50
LOCKFILE=lock.txt
if [ -e ${LOCKFILE} ]; then
echo "lockfile exists"
if kill -0 `cat ${LOCKFILE}`; then
echo "script runs in mem"
lock_date=`date -r ${LOCKFILE} +%s`
now=`date +%s`
lock_age=$(($now-$lock_date))
if [ $lock_ag e -gt $age_max_sec ]; then
echo "DoubleDDNS (no2runKILL)"
kill `cat ${LOCKFILE}`
else
echo "DoubleDDNS (no2runOK), age $lock_age seconds, quit this run"
exit 1
fi
else
echo "not allready running, go ahead"
fi
fi
echo "working on"
# overkill???? just in case, scorched earth check.
filename=${0##*/}
for pid in $(pidof $filename); do
if [ $pid != $$ ]; then
echo "DoubleDDNS (no3runKILL)"
kill -9 $pid
fi
done
# make sure the lockfile is removed when we exit and then claim it
trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
echo $$ > ${LOCKFILE}
# main program here
rm -f ${LOCKFILE}
echo "done"
마지막 실행 기간을 확인하려면 잠금 파일을 사용해야 할 것 같습니다. 따라서 pid를 사용하여 잠금 파일을 만듭니다. 잠긴 파일이 설정된 초 제한보다 오래되지 않은 경우 종료합니다. 오래된 경우 이전 인스턴스를 종료합니다. 내 라우터에서 이를 확인할 수 있는 더 좋은 방법이 없습니다.
초토검사를 해야 하나요, 아니면 너무 과한가요? 합법적인 잠금 파일 검사를 완료한 후 메모리에 남아 있지만 손상된 프로세스가 있는지 다시 검사하고 발견되면 종료합니다. 문제는 결국 실제 재난이 다시 발생하고 정기적인 청소가 실패할 때까지 테스트할 방법이 없다는 것입니다. 너무 치명적이지 않았다면...
NTP 서비스의 가용성은 시간 제한 잠금 및 자살 약에 영향을 미칠 수 있다는 점에 유의해야 합니다. 예를 들어, 위 스크립트를 처음 실행하면 NTP 복구 시간 약 4초 전에 발생합니다. 그러므로 우리는 이런 것들을 고려해야 합니다.
DopeGhoti에서 제공하는 위의 자살약은 매우 효과적입니다. 이제 어떤 조합을 사용할지 결정하는 문제만 남았습니다. 아니면 모두? 파일 잠금, 시간 제한 해제, 초토화 및 자살. 글쎄, 그것은 과잉처럼 들리지만 그들 중 어느 것도 서로 반대하는 것이 아니라 완벽한 (편집증적인) 조화로 작동하는 것으로 보입니다. 의견을 환영합니다.