일주일에 한 번 전체 백업을 수행하고 그렇지 않은 경우 매일 증분 백업을 수행하는 백업 스크립트를 만들고 싶습니다.
경과 일수에 따라 조건을 어떻게 설정하나요? 따라서 일주일이 지나면 전체 백업을 수행하고, 그렇지 않으면 마지막 증분 백업을 덮어씁니다.
/etc/cron.weekly 및 /etc/cron.daily에 동일한 스크립트를 추가하겠습니다.
답변1
다음을 수행할 수 있습니다.
day_of_week=$(date '+%w')
# or with recent bash
printf -v day_of_week '%(%w)T' -1
그 다음에
case $day_of_week in
0) do_full_backup ;;
*) do_incremental_backup ;;
esac
그런 다음 매일 백업 스크립트를 실행하여 전체 백업을 수행할지 아니면 증분 백업을 수행할지 결정합니다.
답변2
경과 일수에 따라 조건을 어떻게 설정하나요?
오늘 날짜뿐만 아니라 마지막 전체 백업 이후 실제 경과된 일수를 확인하려면 마지막 전체 백업의 타임스탬프를 저장하여 확인해야 합니다.
가장 간단한 방법은 경과된 시간(초)인 유닉스 타임스탬프를 확인하는 것입니다.
#!/bin/bash
file=last_full
elapsed=999999999
min_interval=$((6*86400 + 12*3600)) # 6 d + 12 h
now=$(date +%s)
if [[ -f "$file" ]]; then
elapsed=$(( now - $(< "$file") ))
fi
if (( elapsed > min_interval )); then
echo run full backup...
echo "$now" > "$file"
else
echo run incremental backup...
fi
days=$(( elapsed / 86400 ))
또는 먼저 또는 반올림을 사용하여 초를 일로 변환하세요 days_rounded=$(( (elapsed + 86400/2) / 86400 ))
.
이렇게 하면 스크립트가 일요일에 누락되더라도 문제가 되지 않으며 다음 실행 시(예: 월요일)에 다음 전체 백업이 실행됩니다. 단점은 이후의 모든 전체 백업도 월요일로 이동된다는 것입니다. 우회할 수는 있지만반품근무일을 확인하세요. 예를 들면 다음과 같습니다.
if (( elapsed > min_interval )) || [[ $(date +%w) = 0 ]]; then
echo run full backup...
...
fi
(6.5일 컷오프는 어느 날 시스템 부하로 인해 스크립트 실행이 약간 지연되어 다음 간격이 하루 전체보다 몇 초 짧아지는 경우 문제를 방지하기 위한 것입니다.)
/etc/cron.weekly 및 /etc/cron.daily에 동일한 스크립트를 추가하겠습니다.
두 곳 모두에서 실행하면 일요일에 두 번 실행됩니다. (또는 cron.weekly
그날 실행 중인 모든 항목.) 스크립트 자체에서 수행해야 할 작업을 확인하는 경우 에서 실행할 수 있습니다 cron.daily
.
and를 사용하는 cron.daily
또 다른 방법 cron.weekly
은 다음에서 두 개의 행을 만드는 것입니다 crontab
.
0 4 * * 0 /path/to/mybackup.sh full
0 4 * * 1-6 /path/to/mybackup.sh incremental
$1
그런 다음 스크립트의 첫 번째 명령줄 인수를 확인하세요 . 이렇게 하면 일요일의 이중 실행을 피할 수 있지만 이전과 동일한 문제가 발생합니다. 일요일 실행을 놓치면 해당 주의 전체 백업이 누락됩니다.
답변3
내 백업 스크립트는 비슷한 작업을 수행합니다. 이전에는 두 개의 전역 변수, dayno
즉 매월 "첫 번째".."네 번째" 주와 dayname
"일요일".."토요일"을 설정했습니다 . 그런 다음 다음 함수는 0
레벨 0 덤프, 1
요일이 일치하는 경우에만 레벨 1 덤프, 2
다른 요일에 대해서는 레벨 2 덤프를 반환합니다. 관련 기능은 다음과 같습니다.
# get_level calculates the appropriate level for the dump from
# the day or the week and the day of the month.
#
function get_level {
put_trace "$trace" "$this_shell" "Calculating level"
day_of_week=$(date $today +%A)
put_debug "$debug" "Today is $day_of_week $(date $today +%d)"
if [[ "$dayname" == "${day_of_week,,}" ]] # Force to lowercase
then
case $(date $today +%d) in
01|02|03|04|05|06|07) week="first" ;;
08|09|10|11|12|13|14) week="second" ;;
15|16|17|18|19|20|21) week="third" ;;
*) week="fourth" ;;
esac
if [[ "$week" == "$dayno" ]]
then
echo 0
else
echo 1
fi
else
echo 2
fi
}
put_trace
및 줄을 무시하십시오 put_debug
. 이를 사용하려면 지원하는 bash 라이브러리가 필요합니다.
date $today +%A
날짜 이름을 반환합니다( $today
명령줄에서 변경할 수 있으며 현재 날짜로 읽으시면 됩니다). 요일이 레벨 1 및 레벨 0 백업을 완료할 시간과 일치하면 해당 월의 어느 주인지 확인하고, 그렇지 않으면 레벨 2로 돌아갑니다. 사례 설명은 조잡할 수 있지만 명확하고 작동합니다!
필요에 따라 자유롭게 복사하세요. 이 스크립트의 일부는 약 3년 동안 다양한 시스템에서 실행되었으며 생성된 덤프가 때때로 복원되었으므로 작동합니다.
답변4
저는 다음과 같이 설정하겠습니다.
if [ "$(date '+%w')" -eq 0 ]; then
backup_full
else
backup_incremental
fi