cron/crontab을 통해 정기적으로 실행되는 쉘 스크립트가 있습니다. 나는 sleep
몇 분 동안 명령을 내렸습니다 .
sleep 5m # Waits 5 minutes.
이후에 수행되는 작업은 다른(독립) 프로세스에 의해 동기화되어야 하는 파일의 일관된 상태에 따라 달라지기 때문에 그렇게 해야 합니다.
내 컴퓨터가 절전/일시 중지 모드에서 다시 돌아오면 스크립트 실행을 계속하고 싶지 않습니다(컴퓨터가 4분 59초 후에 깨어나 파일이 아직 동기화되지 않을 수 있기 때문입니다).
일시 중지 상태에서 깨어난 지 5분 이상 지났다는 것을 쉘 스크립트에서 어떻게 확인할 수 있나요?
(날짜가 /var/log/pm-suspend.log
내 시스템에 업데이트되지 않는 것 같습니다)
답변1
무엇보다도 sleep
정지 시간을 고려하지 않는다는 점에 유의하십시오.
예를 들어, 명령을 실행하고 sleep 5m
컴퓨터를 일시 중단한 다음 4분 후에 절전 모드를 해제하면 명령은 컴퓨터 sleep
를 시작한 지 9분 후에 종료됩니다. 정지되지 않은 5분 동안 절전 모드로 유지됩니다.
이를 염두에 두고, 찾고 있는 해킹이 전혀 필요하지 않다고 생각합니다. 귀하의 질문은 반대의 잘못된 가정, 즉 sleep 5m
컴퓨터가 일시 중지된 4분 59초와 1초의 깨어 있는 시간 동안 명령이 잠자기 상태일 수 있다는 것을 암시했습니다.
즉, 컴퓨터가 두 순간 사이에 일시 중지되었는지 알 수 있는 한 가지 가능한 방법을 살펴보겠습니다.
매뉴얼 에 설명된 대로 두 개의 시스템 시계가 있습니다 clock_gettime(2)
.
하나는 CLOCK_MONOTONIC
정지 시간을 계산하지 않는다는 것입니다. 임의의 시작점을 기준으로 초 단위 값으로 컴퓨터가 실제로 깨어 있는 데 소요한 시간을 나타냅니다.
CLOCK_REALTIME
현실 세계의 시간을 표현하는 또 다른 것이 있습니다 . 그러나 시계를 조정하면 갑자기 점프하는 경향이 있으므로 완전히 신뢰할 수는 없습니다. 대신에 CLOCK_BOOTTIME
. 이는 컴퓨터가 일시 중지된 시간을 포함하여 임의의 시작점(아마도 시스템 부팅 시간)을 기준으로 한 초 단위의 값입니다.
다음과 같은 명령을 사용하여 이 두 값을 인쇄할 수 있습니다.
python3 -c 'import time; print(time.clock_gettime(time.CLOCK_MONOTONIC))'
python3 -c 'import time; print(time.clock_gettime(time.CLOCK_BOOTTIME))'
(단조 시간을 얻는 더 간단한 구문도 있습니다. 저는 의도적으로 두 종류의 시계에 모두 작동하는 구문을 선택했습니다.)
특정 시점에서 이 두 값을 쿼리하고 차이를 계산합니다. 특정 시점에 다시 이 작업을 수행합니다.
이 두 가지 차이점의 차이는 컴퓨터가 그 사이에 일시 중지된 시간을 나타냅니다. 두 값을 동시에 쿼리할 수 없으므로 약간의 측정 오류가 발생합니다.
답변2
일방 통행
systemd
마지막 재개 시간은 다음과 같은 저널 시스템을 통해 제공되어야 합니다 .
journalctl -r | awk '/resume/ {print $0; exit}'
short-iso
따라서 다음과 같은 형식으로 타임스탬프를 변수에 할당할 수 있습니다 .
lr="$(journalctl -r -o short-iso | awk '/resume/ {printf "%s", $1; exit}')"
다음과 같이 Unix 타임스탬프로 변환하는 동안 여기에 5분을 추가합니다.
lr5="$(date -d "$lr + 5 minutes" +'%s')"
다음과 같은 것을 사용하여 최신 Unix 타임스탬프와 비교/평가합니다.bash
특정 구문):
if [[ "$(date +'%s')" -ge "$lr5" ]]
then
echo "Five minutes have passed since last resume."
# Your command/s here
fi
또 다른 방법
/lib/systemd/system-sleep/
이 템플릿을 사용하여 디렉터리 아래에 스크립트 파일을 배치하면 자신만의 타임스탬프를 만들 수 있습니다 .
#!/bin/sh
case "${1}" in
pre)
# Command(s)/script(s) to execute before system goes to sleep/hibernate
# nothing
;;
post)
# Command(s)/script(s) to execute after system wakes up from sleep/hibernate
# Save your timestamp e.g.:
# /bin/date +'%s' > /home/user/timestamp.log
;;
esac
그리고 사용자 정의 로그 파일의 타임스탬프를 기반으로 구문 분석하고 평가하는 첫 번째 방법과 유사한 논리를 사용하십시오.
알아채다: 네트워크 연결이 필요하거나 이에 의존하는 스크립트를 실행하는 두 번째 방법을 사용하려면 먼저 다음을 참조하세요.스크립트의 네트워크 관련 부분은 /lib/systemd/system-sleep에서 실행되지 않습니다..