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