毎週(フルバックアップ)および毎日(増分)実行されるバックアップスクリプト

毎週(フルバックアップ)および毎日(増分)実行されるバックアップスクリプト

週に1回フルバックアップを実行し、そうでない場合は、毎日増分バックアップを実行するバックアップスクリプトを作成したいと思います。

経過日数に応じて条件をどのように設定しますか?したがって、1週間が経過すると完全バックアップが実行され、そうでない場合は最後の増分バックアップが上書きされます。

/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

経過日数に応じて条件をどのように設定しますか?

今日の日付だけでなく、最後のフルバックアップから実際に経過した日数を確認するには、最後のフルバックアップのタイムスタンプを保存して確認する必要があります。

最も簡単な方法は、経過時間(秒)であるUnixタイムスタンプを確認することです。

#!/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日のカットオフは、ある日のシステム負荷によってスクリプトの実行が少し遅れ、次の間隔が1日全体より数秒短くなる場合の問題を防ぐためです。)

/etc/cron.weeklyと/etc/cron.dailyに同じスクリプトを追加します。

両方の場所で実行すると、日曜日に2回実行されます。 (またはcron.weeklyその日に実行しているすべての項目。)スクリプト自体で何をすべきかを確認したい場合に実行できますcron.daily

andを使用するcron.dailyもう1つの方法cron.weeklyは、次の2つの行を作成することですcrontab

0 4 * * 0   /path/to/mybackup.sh full
0 4 * * 1-6 /path/to/mybackup.sh incremental

$1次に、スクリプトの最初のコマンドライン引数を確認してください。これにより、日曜日の二重実行を回避できますが、以前と同じ問題が発生します。日曜日の実行を見逃すと、その注意の完全バックアップがありません。

答え3

私のバックアップスクリプトは同様のことをします。以前は、2つのグローバル変数、daynoつまり毎月「最初の」..「4番目」の週と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

関連情報