쉘 스크립트에서 지정된 시간에 함수가 실행되도록 예약하는 방법은 무엇입니까?

쉘 스크립트에서 지정된 시간에 함수가 실행되도록 예약하는 방법은 무엇입니까?

Bash 스크립트에는 스크립트가 실행될 때 실행해야 하는 일부 코드와 특정 시간에 실행하려는 함수가 있습니다. 어떻게 해야 하나요?

# Do this now
read -s -p "Password: " password

backup() {
  7z ... -p$password
}

# Do this starting at 5am - how?
while true; do
  backup
  sleep 86400
done

보았지만 at매뉴얼 페이지가 매우 드물고 예제가 없습니다. 어떻게 정리해야 할지 모르겠어요기능. 이 기능을 외부 파일로 추출해야 합니까?

이것이 XY 문제라면 매일 아침 5시에 비밀번호로 보호된 백업을 수행하고 싶습니다. 스크립트의 첫 번째 부분은 비밀번호를 요청 read하고 환경 변수를 통해 비밀번호를 제공하는 방식 으로 작동합니다 7z. 아카이브 부분은 while true;"일일" 부분을 구현하기 위해 86400초 동안 휴면하는 루프에 들어갈 수 있습니다. 문제는 오전 5시부터 시작됐다. cron비밀번호는 한 번 입력하는 것보다 덜 안전한 파일에 저장해야 하므로 좋은 옵션은 아닌 것 같습니다.

답변1

내 계산이 맞다면:

sleep $(( 86400 + 5*3600 - $(date +%s) % 86400 ))
echo "it's 5 in the morning (UTC)"

$(date +%s)= 1970년 초 이후의 현재 시간(UTC)
$(date +%s) % 86400= 하루의 일부, 지난 자정 이후의 초 수(UTC)
86400 + 5*3600= 지난 자정부터 내일 오전 5시까지의 초 수
86400 + 5*3600 - $(date +%s) % 86400= 현재와 5 사이의 초 수 내일 오전 (UTC)

물론, 현재 시간이 UTC 자정과 목표 시간 사이에 있고 현지 시간대에 맞게 목표 시간을 조정해야 하는 경우에는 중단됩니다.

아마도 더 간단한 것은 다음과 같습니다.

sleep $(( $(date -d '05:00 tomorrow' +%s) - $(date +%s) ))

자정이 지나면 추가 24시간도 건너뛰지만 최소한 현지 시간은 계산됩니다.

비밀번호는 파일에 저장해야 하므로 한 번 입력하는 것보다 보안성이 떨어집니다.

보호하려는 대상에 따라 암호가 tmpfs디스크에 도달하지 않도록 메모리 내 파일 시스템에 암호를 넣을 수도 있습니다. systemd 시스템에서는 /run이어야 tmpfs하지만 확실히 하는 것이 더 좋습니다.

또한 백업 수행 방법에 따라 원격으로 백업을 보내는 데만 사용할 수 있는(읽지는 못함) SSH 키를 준비할 수도 있습니다. 또는 공개 키 암호화를 사용하면 백업이 기록된 호스트에 백업의 공개 부분만 있으면 됩니다.

답변2

at쉘 함수를 실행할 수는 없지만 at신호를 보내고 실행 중인 스크립트에서 신호를 기다렸다가 신호가 도착하면 함수를 시작할 수 있습니다.

이 스크립트가 다음과 같이 root실행 --user되면 systemd-run.

#! /bin/bash

backup() {
  : 7z ... -p$password
}

trap sighandler_usr1 USR1

sighandler_usr1 () {
  trap '' USR1 # do not execute backup() several times in parallel
  echo "PID $$ just received SIGUSR1"
  backup
  trap sighandler_usr1 USR1
  request_signal
}

request_signal () {
  : use e.g. at or systemd-run to send SIGUSR1 to this shell
  systemd-run --user --on-calendar=05:00 kill -USR1 $$
}

request_signal

while true; do
  read -s -n 1000 ignore
done

관련 정보